aboutsummaryrefslogtreecommitdiff
path: root/SOURCES
diff options
context:
space:
mode:
Diffstat (limited to 'SOURCES')
-rw-r--r--SOURCES/0001-amd-pstate.patch578
-rw-r--r--SOURCES/0001-ntsync.patch (renamed from SOURCES/winesync.patch)4175
-rw-r--r--SOURCES/kernel-aarch64-16k-debug-fedora.config2
-rw-r--r--SOURCES/kernel-aarch64-16k-fedora.config2
-rw-r--r--SOURCES/kernel-aarch64-64k-debug-rhel.config2
-rw-r--r--SOURCES/kernel-aarch64-64k-rhel.config2
-rw-r--r--SOURCES/kernel-aarch64-debug-fedora.config2
-rw-r--r--SOURCES/kernel-aarch64-debug-rhel.config2
-rw-r--r--SOURCES/kernel-aarch64-fedora.config2
-rw-r--r--SOURCES/kernel-aarch64-rhel.config2
-rw-r--r--SOURCES/kernel-aarch64-rt-debug-rhel.config2
-rw-r--r--SOURCES/kernel-aarch64-rt-rhel.config2
-rw-r--r--SOURCES/kernel-ppc64le-debug-fedora.config2
-rw-r--r--SOURCES/kernel-ppc64le-debug-rhel.config2
-rw-r--r--SOURCES/kernel-ppc64le-fedora.config2
-rw-r--r--SOURCES/kernel-ppc64le-rhel.config2
-rw-r--r--SOURCES/kernel-s390x-debug-fedora.config2
-rw-r--r--SOURCES/kernel-s390x-debug-rhel.config2
-rw-r--r--SOURCES/kernel-s390x-fedora.config2
-rw-r--r--SOURCES/kernel-s390x-rhel.config2
-rw-r--r--SOURCES/kernel-s390x-zfcpdump-rhel.config2
-rw-r--r--SOURCES/kernel-x86_64-debug-fedora.config2
-rw-r--r--SOURCES/kernel-x86_64-debug-rhel.config2
-rw-r--r--SOURCES/kernel-x86_64-fedora.config2
-rw-r--r--SOURCES/kernel-x86_64-rhel.config2
-rw-r--r--SOURCES/kernel-x86_64-rt-debug-rhel.config2
-rw-r--r--SOURCES/kernel-x86_64-rt-rhel.config2
-rw-r--r--SOURCES/kernel.changelog5
-rw-r--r--SOURCES/patch-6.7-redhat.patch386
29 files changed, 2653 insertions, 2541 deletions
diff --git a/SOURCES/0001-amd-pstate.patch b/SOURCES/0001-amd-pstate.patch
new file mode 100644
index 0000000..d7fd4b3
--- /dev/null
+++ b/SOURCES/0001-amd-pstate.patch
@@ -0,0 +1,578 @@
+From 1449b07b2bd2af451bba8ba17f7b01cf30b6471f Mon Sep 17 00:00:00 2001
+From: Peter Jung <admin@ptr1337.dev>
+Date: Fri, 23 Feb 2024 17:11:08 +0100
+Subject: [PATCH 1/7] amd-pstate
+
+Signed-off-by: Peter Jung <admin@ptr1337.dev>
+---
+ .../admin-guide/kernel-parameters.txt | 5 +
+ Documentation/admin-guide/pm/amd-pstate.rst | 59 +++++-
+ arch/x86/Kconfig | 5 +-
+ drivers/acpi/cppc_acpi.c | 13 ++
+ drivers/acpi/processor_driver.c | 6 +
+ drivers/cpufreq/amd-pstate.c | 179 +++++++++++++++++-
+ include/acpi/cppc_acpi.h | 5 +
+ include/linux/amd-pstate.h | 10 +
+ include/linux/cpufreq.h | 1 +
+ 9 files changed, 272 insertions(+), 11 deletions(-)
+
+diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
+index b72e2049c487..95164b35f973 100644
+--- a/Documentation/admin-guide/kernel-parameters.txt
++++ b/Documentation/admin-guide/kernel-parameters.txt
+@@ -363,6 +363,11 @@
+ selects a performance level in this range and appropriate
+ to the current workload.
+
++ amd_prefcore=
++ [X86]
++ disable
++ Disable amd-pstate preferred core.
++
+ amijoy.map= [HW,JOY] Amiga joystick support
+ Map of devices attached to JOY0DAT and JOY1DAT
+ Format: <a>,<b>
+diff --git a/Documentation/admin-guide/pm/amd-pstate.rst b/Documentation/admin-guide/pm/amd-pstate.rst
+index 1cf40f69278c..0b832ff529db 100644
+--- a/Documentation/admin-guide/pm/amd-pstate.rst
++++ b/Documentation/admin-guide/pm/amd-pstate.rst
+@@ -300,8 +300,8 @@ platforms. The AMD P-States mechanism is the more performance and energy
+ efficiency frequency management method on AMD processors.
+
+
+-AMD Pstate Driver Operation Modes
+-=================================
++``amd-pstate`` Driver Operation Modes
++======================================
+
+ ``amd_pstate`` CPPC has 3 operation modes: autonomous (active) mode,
+ non-autonomous (passive) mode and guided autonomous (guided) mode.
+@@ -353,6 +353,48 @@ is activated. In this mode, driver requests minimum and maximum performance
+ level and the platform autonomously selects a performance level in this range
+ and appropriate to the current workload.
+
++``amd-pstate`` Preferred Core
++=================================
++
++The core frequency is subjected to the process variation in semiconductors.
++Not all cores are able to reach the maximum frequency respecting the
++infrastructure limits. Consequently, AMD has redefined the concept of
++maximum frequency of a part. This means that a fraction of cores can reach
++maximum frequency. To find the best process scheduling policy for a given
++scenario, OS needs to know the core ordering informed by the platform through
++highest performance capability register of the CPPC interface.
++
++``amd-pstate`` preferred core enables the scheduler to prefer scheduling on
++cores that can achieve a higher frequency with lower voltage. The preferred
++core rankings can dynamically change based on the workload, platform conditions,
++thermals and ageing.
++
++The priority metric will be initialized by the ``amd-pstate`` driver. The ``amd-pstate``
++driver will also determine whether or not ``amd-pstate`` preferred core is
++supported by the platform.
++
++``amd-pstate`` driver will provide an initial core ordering when the system boots.
++The platform uses the CPPC interfaces to communicate the core ranking to the
++operating system and scheduler to make sure that OS is choosing the cores
++with highest performance firstly for scheduling the process. When ``amd-pstate``
++driver receives a message with the highest performance change, it will
++update the core ranking and set the cpu's priority.
++
++``amd-pstate`` Preferred Core Switch
++=================================
++Kernel Parameters
++-----------------
++
++``amd-pstate`` peferred core`` has two states: enable and disable.
++Enable/disable states can be chosen by different kernel parameters.
++Default enable ``amd-pstate`` preferred core.
++
++``amd_prefcore=disable``
++
++For systems that support ``amd-pstate`` preferred core, the core rankings will
++always be advertised by the platform. But OS can choose to ignore that via the
++kernel parameter ``amd_prefcore=disable``.
++
+ User Space Interface in ``sysfs`` - General
+ ===========================================
+
+@@ -385,6 +427,19 @@ control its functionality at the system level. They are located in the
+ to the operation mode represented by that string - or to be
+ unregistered in the "disable" case.
+
++``prefcore``
++ Preferred core state of the driver: "enabled" or "disabled".
++
++ "enabled"
++ Enable the ``amd-pstate`` preferred core.
++
++ "disabled"
++ Disable the ``amd-pstate`` preferred core
++
++
++ This attribute is read-only to check the state of preferred core set
++ by the kernel parameter.
++
+ ``cpupower`` tool support for ``amd-pstate``
+ ===============================================
+
+diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
+index 1566748f16c4..4fd69cd4241a 100644
+--- a/arch/x86/Kconfig
++++ b/arch/x86/Kconfig
+@@ -1054,8 +1054,9 @@ config SCHED_MC
+
+ config SCHED_MC_PRIO
+ bool "CPU core priorities scheduler support"
+- depends on SCHED_MC && CPU_SUP_INTEL
+- select X86_INTEL_PSTATE
++ depends on SCHED_MC
++ select X86_INTEL_PSTATE if CPU_SUP_INTEL
++ select X86_AMD_PSTATE if CPU_SUP_AMD && ACPI
+ select CPU_FREQ
+ default y
+ help
+diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c
+index 7ff269a78c20..ad388a0e8484 100644
+--- a/drivers/acpi/cppc_acpi.c
++++ b/drivers/acpi/cppc_acpi.c
+@@ -1154,6 +1154,19 @@ int cppc_get_nominal_perf(int cpunum, u64 *nominal_perf)
+ return cppc_get_perf(cpunum, NOMINAL_PERF, nominal_perf);
+ }
+
++/**
++ * cppc_get_highest_perf - Get the highest performance register value.
++ * @cpunum: CPU from which to get highest performance.
++ * @highest_perf: Return address.
++ *
++ * Return: 0 for success, -EIO otherwise.
++ */
++int cppc_get_highest_perf(int cpunum, u64 *highest_perf)
++{
++ return cppc_get_perf(cpunum, HIGHEST_PERF, highest_perf);
++}
++EXPORT_SYMBOL_GPL(cppc_get_highest_perf);
++
+ /**
+ * cppc_get_epp_perf - Get the epp register value.
+ * @cpunum: CPU from which to get epp preference value.
+diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c
+index 4bd16b3f0781..67db60eda370 100644
+--- a/drivers/acpi/processor_driver.c
++++ b/drivers/acpi/processor_driver.c
+@@ -27,6 +27,7 @@
+ #define ACPI_PROCESSOR_NOTIFY_PERFORMANCE 0x80
+ #define ACPI_PROCESSOR_NOTIFY_POWER 0x81
+ #define ACPI_PROCESSOR_NOTIFY_THROTTLING 0x82
++#define ACPI_PROCESSOR_NOTIFY_HIGEST_PERF_CHANGED 0x85
+
+ MODULE_AUTHOR("Paul Diefenbaugh");
+ MODULE_DESCRIPTION("ACPI Processor Driver");
+@@ -83,6 +84,11 @@ static void acpi_processor_notify(acpi_handle handle, u32 event, void *data)
+ acpi_bus_generate_netlink_event(device->pnp.device_class,
+ dev_name(&device->dev), event, 0);
+ break;
++ case ACPI_PROCESSOR_NOTIFY_HIGEST_PERF_CHANGED:
++ cpufreq_update_limits(pr->id);
++ acpi_bus_generate_netlink_event(device->pnp.device_class,
++ dev_name(&device->dev), event, 0);
++ break;
+ default:
+ acpi_handle_debug(handle, "Unsupported event [0x%x]\n", event);
+ break;
+diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c
+index 1791d37fbc53..54df68773620 100644
+--- a/drivers/cpufreq/amd-pstate.c
++++ b/drivers/cpufreq/amd-pstate.c
+@@ -37,6 +37,7 @@
+ #include <linux/uaccess.h>
+ #include <linux/static_call.h>
+ #include <linux/amd-pstate.h>
++#include <linux/topology.h>
+
+ #include <acpi/processor.h>
+ #include <acpi/cppc_acpi.h>
+@@ -64,6 +65,7 @@ static struct cpufreq_driver amd_pstate_driver;
+ static struct cpufreq_driver amd_pstate_epp_driver;
+ static int cppc_state = AMD_PSTATE_UNDEFINED;
+ static bool cppc_enabled;
++static bool amd_pstate_prefcore = true;
+
+ /*
+ * AMD Energy Preference Performance (EPP)
+@@ -296,14 +298,12 @@ static int pstate_init_perf(struct amd_cpudata *cpudata)
+ &cap1);
+ if (ret)
+ return ret;
+-
+- /*
+- * TODO: Introduce AMD specific power feature.
+- *
+- * CPPC entry doesn't indicate the highest performance in some ASICs.
++
++ /* Some CPUs have different highest_perf from others, it is safer
++ * to read it than to assume some erroneous value, leading to performance issues.
+ */
+ highest_perf = amd_get_highest_perf();
+- if (highest_perf > AMD_CPPC_HIGHEST_PERF(cap1))
++ if(highest_perf > AMD_CPPC_HIGHEST_PERF(cap1))
+ highest_perf = AMD_CPPC_HIGHEST_PERF(cap1);
+
+ WRITE_ONCE(cpudata->highest_perf, highest_perf);
+@@ -311,6 +311,7 @@ static int pstate_init_perf(struct amd_cpudata *cpudata)
+ WRITE_ONCE(cpudata->nominal_perf, AMD_CPPC_NOMINAL_PERF(cap1));
+ WRITE_ONCE(cpudata->lowest_nonlinear_perf, AMD_CPPC_LOWNONLIN_PERF(cap1));
+ WRITE_ONCE(cpudata->lowest_perf, AMD_CPPC_LOWEST_PERF(cap1));
++ WRITE_ONCE(cpudata->prefcore_ranking, AMD_CPPC_HIGHEST_PERF(cap1));
+ WRITE_ONCE(cpudata->min_limit_perf, AMD_CPPC_LOWEST_PERF(cap1));
+ return 0;
+ }
+@@ -324,8 +325,11 @@ static int cppc_init_perf(struct amd_cpudata *cpudata)
+ if (ret)
+ return ret;
+
++ /* Some CPUs have different highest_perf from others, it is safer
++ * to read it than to assume some erroneous value, leading to performance issues.
++ */
+ highest_perf = amd_get_highest_perf();
+- if (highest_perf > cppc_perf.highest_perf)
++ if(highest_perf > cppc_perf.highest_perf)
+ highest_perf = cppc_perf.highest_perf;
+
+ WRITE_ONCE(cpudata->highest_perf, highest_perf);
+@@ -334,6 +338,7 @@ static int cppc_init_perf(struct amd_cpudata *cpudata)
+ WRITE_ONCE(cpudata->lowest_nonlinear_perf,
+ cppc_perf.lowest_nonlinear_perf);
+ WRITE_ONCE(cpudata->lowest_perf, cppc_perf.lowest_perf);
++ WRITE_ONCE(cpudata->prefcore_ranking, cppc_perf.highest_perf);
+ WRITE_ONCE(cpudata->min_limit_perf, cppc_perf.lowest_perf);
+
+ if (cppc_state == AMD_PSTATE_ACTIVE)
+@@ -706,6 +711,114 @@ static void amd_perf_ctl_reset(unsigned int cpu)
+ wrmsrl_on_cpu(cpu, MSR_AMD_PERF_CTL, 0);
+ }
+
++/*
++ * Set amd-pstate preferred core enable can't be done directly from cpufreq callbacks
++ * due to locking, so queue the work for later.
++ */
++static void amd_pstste_sched_prefcore_workfn(struct work_struct *work)
++{
++ sched_set_itmt_support();
++}
++static DECLARE_WORK(sched_prefcore_work, amd_pstste_sched_prefcore_workfn);
++
++/*
++ * Get the highest performance register value.
++ * @cpu: CPU from which to get highest performance.
++ * @highest_perf: Return address.
++ *
++ * Return: 0 for success, -EIO otherwise.
++ */
++static int amd_pstate_get_highest_perf(int cpu, u32 *highest_perf)
++{
++ int ret;
++
++ if (boot_cpu_has(X86_FEATURE_CPPC)) {
++ u64 cap1;
++
++ ret = rdmsrl_safe_on_cpu(cpu, MSR_AMD_CPPC_CAP1, &cap1);
++ if (ret)
++ return ret;
++ WRITE_ONCE(*highest_perf, AMD_CPPC_HIGHEST_PERF(cap1));
++ } else {
++ u64 cppc_highest_perf;
++
++ ret = cppc_get_highest_perf(cpu, &cppc_highest_perf);
++ if (ret)
++ return ret;
++ WRITE_ONCE(*highest_perf, cppc_highest_perf);
++ }
++
++ return (ret);
++}
++
++#define CPPC_MAX_PERF U8_MAX
++
++static void amd_pstate_init_prefcore(struct amd_cpudata *cpudata)
++{
++ int ret, prio;
++ u32 highest_perf;
++
++ ret = amd_pstate_get_highest_perf(cpudata->cpu, &highest_perf);
++ if (ret)
++ return;
++
++ cpudata->hw_prefcore = true;
++ /* check if CPPC preferred core feature is enabled*/
++ if (highest_perf < CPPC_MAX_PERF)
++ prio = (int)highest_perf;
++ else {
++ pr_debug("AMD CPPC preferred core is unsupported!\n");
++ cpudata->hw_prefcore = false;
++ return;
++ }
++
++ if (!amd_pstate_prefcore)
++ return;
++
++ /*
++ * The priorities can be set regardless of whether or not
++ * sched_set_itmt_support(true) has been called and it is valid to
++ * update them at any time after it has been called.
++ */
++ sched_set_itmt_core_prio(prio, cpudata->cpu);
++
++ schedule_work(&sched_prefcore_work);
++}
++
++static void amd_pstate_update_limits(unsigned int cpu)
++{
++ struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
++ struct amd_cpudata *cpudata = policy->driver_data;
++ u32 prev_high = 0, cur_high = 0;
++ int ret;
++ bool highest_perf_changed = false;
++
++ mutex_lock(&amd_pstate_driver_lock);
++ if ((!amd_pstate_prefcore) || (!cpudata->hw_prefcore))
++ goto free_cpufreq_put;
++
++ ret = amd_pstate_get_highest_perf(cpu, &cur_high);
++ if (ret)
++ goto free_cpufreq_put;
++
++ prev_high = READ_ONCE(cpudata->prefcore_ranking);
++ if (prev_high != cur_high) {
++ highest_perf_changed = true;
++ WRITE_ONCE(cpudata->prefcore_ranking, cur_high);
++
++ if (cur_high < CPPC_MAX_PERF)
++ sched_set_itmt_core_prio((int)cur_high, cpu);
++ }
++
++free_cpufreq_put:
++ cpufreq_cpu_put(policy);
++
++ if (!highest_perf_changed)
++ cpufreq_update_policy(cpu);
++
++ mutex_unlock(&amd_pstate_driver_lock);
++}
++
+ static int amd_pstate_cpu_init(struct cpufreq_policy *policy)
+ {
+ int min_freq, max_freq, nominal_freq, lowest_nonlinear_freq, ret;
+@@ -727,6 +840,8 @@ static int amd_pstate_cpu_init(struct cpufreq_policy *policy)
+
+ cpudata->cpu = policy->cpu;
+
++ amd_pstate_init_prefcore(cpudata);
++
+ ret = amd_pstate_init_perf(cpudata);
+ if (ret)
+ goto free_cpudata1;
+@@ -877,6 +992,28 @@ static ssize_t show_amd_pstate_highest_perf(struct cpufreq_policy *policy,
+ return sysfs_emit(buf, "%u\n", perf);
+ }
+
++static ssize_t show_amd_pstate_prefcore_ranking(struct cpufreq_policy *policy,
++ char *buf)
++{
++ u32 perf;
++ struct amd_cpudata *cpudata = policy->driver_data;
++
++ perf = READ_ONCE(cpudata->prefcore_ranking);
++
++ return sysfs_emit(buf, "%u\n", perf);
++}
++
++static ssize_t show_amd_pstate_hw_prefcore(struct cpufreq_policy *policy,
++ char *buf)
++{
++ bool hw_prefcore;
++ struct amd_cpudata *cpudata = policy->driver_data;
++
++ hw_prefcore = READ_ONCE(cpudata->hw_prefcore);
++
++ return sysfs_emit(buf, "%s\n", str_enabled_disabled(hw_prefcore));
++}
++
+ static ssize_t show_energy_performance_available_preferences(
+ struct cpufreq_policy *policy, char *buf)
+ {
+@@ -1074,18 +1211,29 @@ static ssize_t status_store(struct device *a, struct device_attribute *b,
+ return ret < 0 ? ret : count;
+ }
+
++static ssize_t prefcore_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ return sysfs_emit(buf, "%s\n", str_enabled_disabled(amd_pstate_prefcore));
++}
++
+ cpufreq_freq_attr_ro(amd_pstate_max_freq);
+ cpufreq_freq_attr_ro(amd_pstate_lowest_nonlinear_freq);
+
+ cpufreq_freq_attr_ro(amd_pstate_highest_perf);
++cpufreq_freq_attr_ro(amd_pstate_prefcore_ranking);
++cpufreq_freq_attr_ro(amd_pstate_hw_prefcore);
+ cpufreq_freq_attr_rw(energy_performance_preference);
+ cpufreq_freq_attr_ro(energy_performance_available_preferences);
+ static DEVICE_ATTR_RW(status);
++static DEVICE_ATTR_RO(prefcore);
+
+ static struct freq_attr *amd_pstate_attr[] = {
+ &amd_pstate_max_freq,
+ &amd_pstate_lowest_nonlinear_freq,
+ &amd_pstate_highest_perf,
++ &amd_pstate_prefcore_ranking,
++ &amd_pstate_hw_prefcore,
+ NULL,
+ };
+
+@@ -1093,6 +1241,8 @@ static struct freq_attr *amd_pstate_epp_attr[] = {
+ &amd_pstate_max_freq,
+ &amd_pstate_lowest_nonlinear_freq,
+ &amd_pstate_highest_perf,
++ &amd_pstate_prefcore_ranking,
++ &amd_pstate_hw_prefcore,
+ &energy_performance_preference,
+ &energy_performance_available_preferences,
+ NULL,
+@@ -1100,6 +1250,7 @@ static struct freq_attr *amd_pstate_epp_attr[] = {
+
+ static struct attribute *pstate_global_attributes[] = {
+ &dev_attr_status.attr,
++ &dev_attr_prefcore.attr,
+ NULL
+ };
+
+@@ -1151,6 +1302,8 @@ static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy)
+ cpudata->cpu = policy->cpu;
+ cpudata->epp_policy = 0;
+
++ amd_pstate_init_prefcore(cpudata);
++
+ ret = amd_pstate_init_perf(cpudata);
+ if (ret)
+ goto free_cpudata1;
+@@ -1432,6 +1585,7 @@ static struct cpufreq_driver amd_pstate_driver = {
+ .suspend = amd_pstate_cpu_suspend,
+ .resume = amd_pstate_cpu_resume,
+ .set_boost = amd_pstate_set_boost,
++ .update_limits = amd_pstate_update_limits,
+ .name = "amd-pstate",
+ .attr = amd_pstate_attr,
+ };
+@@ -1446,6 +1600,7 @@ static struct cpufreq_driver amd_pstate_epp_driver = {
+ .online = amd_pstate_epp_cpu_online,
+ .suspend = amd_pstate_epp_suspend,
+ .resume = amd_pstate_epp_resume,
++ .update_limits = amd_pstate_update_limits,
+ .name = "amd-pstate-epp",
+ .attr = amd_pstate_epp_attr,
+ };
+@@ -1567,7 +1722,17 @@ static int __init amd_pstate_param(char *str)
+
+ return amd_pstate_set_driver(mode_idx);
+ }
++
++static int __init amd_prefcore_param(char *str)
++{
++ if (!strcmp(str, "disable"))
++ amd_pstate_prefcore = false;
++
++ return 0;
++}
++
+ early_param("amd_pstate", amd_pstate_param);
++early_param("amd_prefcore", amd_prefcore_param);
+
+ MODULE_AUTHOR("Huang Rui <ray.huang@amd.com>");
+ MODULE_DESCRIPTION("AMD Processor P-state Frequency Driver");
+diff --git a/include/acpi/cppc_acpi.h b/include/acpi/cppc_acpi.h
+index 6126c977ece0..c0b69ffe7bdb 100644
+--- a/include/acpi/cppc_acpi.h
++++ b/include/acpi/cppc_acpi.h
+@@ -139,6 +139,7 @@ struct cppc_cpudata {
+ #ifdef CONFIG_ACPI_CPPC_LIB
+ extern int cppc_get_desired_perf(int cpunum, u64 *desired_perf);
+ extern int cppc_get_nominal_perf(int cpunum, u64 *nominal_perf);
++extern int cppc_get_highest_perf(int cpunum, u64 *highest_perf);
+ extern int cppc_get_perf_ctrs(int cpu, struct cppc_perf_fb_ctrs *perf_fb_ctrs);
+ extern int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls);
+ extern int cppc_set_enable(int cpu, bool enable);
+@@ -165,6 +166,10 @@ static inline int cppc_get_nominal_perf(int cpunum, u64 *nominal_perf)
+ {
+ return -ENOTSUPP;
+ }
++static inline int cppc_get_highest_perf(int cpunum, u64 *highest_perf)
++{
++ return -ENOTSUPP;
++}
+ static inline int cppc_get_perf_ctrs(int cpu, struct cppc_perf_fb_ctrs *perf_fb_ctrs)
+ {
+ return -ENOTSUPP;
+diff --git a/include/linux/amd-pstate.h b/include/linux/amd-pstate.h
+index 6ad02ad9c7b4..d21838835abd 100644
+--- a/include/linux/amd-pstate.h
++++ b/include/linux/amd-pstate.h
+@@ -39,11 +39,16 @@ struct amd_aperf_mperf {
+ * @cppc_req_cached: cached performance request hints
+ * @highest_perf: the maximum performance an individual processor may reach,
+ * assuming ideal conditions
++ * For platforms that do not support the preferred core feature, the
++ * highest_pef may be configured with 166 or 255, to avoid max frequency
++ * calculated wrongly. we take the fixed value as the highest_perf.
+ * @nominal_perf: the maximum sustained performance level of the processor,
+ * assuming ideal operating conditions
+ * @lowest_nonlinear_perf: the lowest performance level at which nonlinear power
+ * savings are achieved
+ * @lowest_perf: the absolute lowest performance level of the processor
++ * @prefcore_ranking: the preferred core ranking, the higher value indicates a higher
++ * priority.
+ * @max_freq: the frequency that mapped to highest_perf
+ * @min_freq: the frequency that mapped to lowest_perf
+ * @nominal_freq: the frequency that mapped to nominal_perf
+@@ -52,6 +57,9 @@ struct amd_aperf_mperf {
+ * @prev: Last Aperf/Mperf/tsc count value read from register
+ * @freq: current cpu frequency value
+ * @boost_supported: check whether the Processor or SBIOS supports boost mode
++ * @hw_prefcore: check whether HW supports preferred core featue.
++ * Only when hw_prefcore and early prefcore param are true,
++ * AMD P-State driver supports preferred core featue.
+ * @epp_policy: Last saved policy used to set energy-performance preference
+ * @epp_cached: Cached CPPC energy-performance preference value
+ * @policy: Cpufreq policy value
+@@ -70,6 +78,7 @@ struct amd_cpudata {
+ u32 nominal_perf;
+ u32 lowest_nonlinear_perf;
+ u32 lowest_perf;
++ u32 prefcore_ranking;
+ u32 min_limit_perf;
+ u32 max_limit_perf;
+ u32 min_limit_freq;
+@@ -85,6 +94,7 @@ struct amd_cpudata {
+
+ u64 freq;
+ bool boost_supported;
++ bool hw_prefcore;
+
+ /* EPP feature related attributes*/
+ s16 epp_policy;
+diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
+index 1c5ca92a0555..5d62beea2712 100644
+--- a/include/linux/cpufreq.h
++++ b/include/linux/cpufreq.h
+@@ -263,6 +263,7 @@ static inline bool cpufreq_supports_freq_invariance(void)
+ return false;
+ }
+ static inline void disable_cpufreq(void) { }
++static inline void cpufreq_update_limits(unsigned int cpu) { }
+ #endif
+
+ #ifdef CONFIG_CPU_FREQ_STAT
+--
+2.43.2
+
diff --git a/SOURCES/winesync.patch b/SOURCES/0001-ntsync.patch
index 459bf54..34a383a 100644
--- a/SOURCES/winesync.patch
+++ b/SOURCES/0001-ntsync.patch
@@ -1,145 +1,135 @@
-From 153c94d81f583dfbd9e4e81eefc6a9b8e83ff06d Mon Sep 17 00:00:00 2001
-From: Zebediah Figura <zfigura@codeweavers.com>
+From 34529eb8302090ff79e04d95a6bb7f5fd48cecb6 Mon Sep 17 00:00:00 2001
+From: Elizabeth Figura <zfigura@codeweavers.com>
Date: Fri, 5 Mar 2021 10:50:45 -0600
-Subject: [PATCH 01/34] winesync: Introduce the winesync driver and character
+Subject: [PATCH 01/32] ntsync: Introduce the ntsync driver and character
device.
+ntsync uses a misc device as the simplest and least intrusive uAPI interface.
+
+Each file description on the device represents an isolated NT instance, intended
+to correspond to a single NT virtual machine.
---
- drivers/misc/Kconfig | 11 +++++++
- drivers/misc/Makefile | 1 +
- drivers/misc/winesync.c | 64 +++++++++++++++++++++++++++++++++++++++++
- 3 files changed, 76 insertions(+)
- create mode 100644 drivers/misc/winesync.c
+ drivers/misc/Kconfig | 9 ++++++++
+ drivers/misc/Makefile | 1 +
+ drivers/misc/ntsync.c | 53 +++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 63 insertions(+)
+ create mode 100644 drivers/misc/ntsync.c
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
-index 94e9fb4cdd76..4f9e3d80a6e8 100644
+index f37c4b8380ae..622eb26ac040 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
-@@ -519,6 +519,17 @@
-
- If you do not intend to run this kernel as a guest, say N.
+@@ -504,6 +504,15 @@ config OPEN_DICE
+ measured boot flow. Userspace can use CDIs for remote attestation
+ and sealing.
-+config WINESYNC
-+ tristate "Synchronization primitives for Wine"
++config NTSYNC
++ tristate "NT synchronization primitive emulation"
+ help
-+ This module provides kernel support for synchronization primitives
-+ used by Wine. It is not a hardware driver.
++ This module provides kernel support for emulation of Windows NT
++ synchronization primitives. It is not a hardware driver.
+
+ To compile this driver as a module, choose M here: the
-+ module will be called winesync.
-+
-+ If unsure, say N.
++ module will be called ntsync.
+
- config TMR_MANAGER
- tristate "Select TMR Manager"
- depends on MICROBLAZE && MB_MANAGER
+ If unsure, say N.
+
+ config VCPU_STALL_DETECTOR
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
-index 2be8542616dd..d061fe45407b 100644
+index f2a4d1ff65d4..bd12e9a3b8c5 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
-@@ -59,6 +59,7 @@
+@@ -59,6 +59,7 @@ obj-$(CONFIG_PVPANIC) += pvpanic/
obj-$(CONFIG_UACCE) += uacce/
obj-$(CONFIG_XILINX_SDFEC) += xilinx_sdfec.o
obj-$(CONFIG_HISI_HIKEY_USB) += hisi_hikey_usb.o
-+obj-$(CONFIG_WINESYNC) += winesync.o
++obj-$(CONFIG_NTSYNC) += ntsync.o
obj-$(CONFIG_HI6421V600_IRQ) += hi6421v600-irq.o
obj-$(CONFIG_OPEN_DICE) += open-dice.o
obj-$(CONFIG_GP_PCI1XXXX) += mchp_pci1xxxx/
-diff --git a/drivers/misc/winesync.c b/drivers/misc/winesync.c
+diff --git a/drivers/misc/ntsync.c b/drivers/misc/ntsync.c
new file mode 100644
-index 000000000000..111f33c5676e
+index 000000000000..9424c6210e51
--- /dev/null
-+++ b/drivers/misc/winesync.c
-@@ -0,0 +1,64 @@
++++ b/drivers/misc/ntsync.c
+@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
-+ * winesync.c - Kernel driver for Wine synchronization primitives
++ * ntsync.c - Kernel driver for NT synchronization primitives
+ *
-+ * Copyright (C) 2021 Zebediah Figura
++ * Copyright (C) 2021-2022 Elizabeth Figura
+ */
+
+#include <linux/fs.h>
+#include <linux/miscdevice.h>
+#include <linux/module.h>
+
-+#define WINESYNC_NAME "winesync"
++#define NTSYNC_NAME "ntsync"
+
-+static int winesync_char_open(struct inode *inode, struct file *file)
++static int ntsync_char_open(struct inode *inode, struct file *file)
+{
+ return nonseekable_open(inode, file);
+}
+
-+static int winesync_char_release(struct inode *inode, struct file *file)
++static int ntsync_char_release(struct inode *inode, struct file *file)
+{
+ return 0;
+}
+
-+static long winesync_char_ioctl(struct file *file, unsigned int cmd,
-+ unsigned long parm)
++static long ntsync_char_ioctl(struct file *file, unsigned int cmd,
++ unsigned long parm)
+{
+ switch (cmd) {
+ default:
-+ return -ENOSYS;
++ return -ENOIOCTLCMD;
+ }
+}
+
-+static const struct file_operations winesync_fops = {
++static const struct file_operations ntsync_fops = {
+ .owner = THIS_MODULE,
-+ .open = winesync_char_open,
-+ .release = winesync_char_release,
-+ .unlocked_ioctl = winesync_char_ioctl,
-+ .compat_ioctl = winesync_char_ioctl,
++ .open = ntsync_char_open,
++ .release = ntsync_char_release,
++ .unlocked_ioctl = ntsync_char_ioctl,
++ .compat_ioctl = ntsync_char_ioctl,
+ .llseek = no_llseek,
+};
+
-+static struct miscdevice winesync_misc = {
++static struct miscdevice ntsync_misc = {
+ .minor = MISC_DYNAMIC_MINOR,
-+ .name = WINESYNC_NAME,
-+ .fops = &winesync_fops,
++ .name = NTSYNC_NAME,
++ .fops = &ntsync_fops,
+};
+
-+static int __init winesync_init(void)
-+{
-+ return misc_register(&winesync_misc);
-+}
-+
-+static void __exit winesync_exit(void)
-+{
-+ misc_deregister(&winesync_misc);
-+}
-+
-+module_init(winesync_init);
-+module_exit(winesync_exit);
++module_misc_device(ntsync_misc);
+
-+MODULE_AUTHOR("Zebediah Figura");
-+MODULE_DESCRIPTION("Kernel driver for Wine synchronization primitives");
++MODULE_AUTHOR("Elizabeth Figura");
++MODULE_DESCRIPTION("Kernel driver for NT synchronization primitives");
+MODULE_LICENSE("GPL");
-+MODULE_ALIAS("devname:" WINESYNC_NAME);
++MODULE_ALIAS("devname:" NTSYNC_NAME);
--
-2.37.3
+2.43.0
-From 1f142d40cb7537bd936a68cadaf0f2a0d94abd62 Mon Sep 17 00:00:00 2001
-From: Zebediah Figura <zfigura@codeweavers.com>
+From a375bffd8ab8d06b81e4b83c9f5577fdc97246f9 Mon Sep 17 00:00:00 2001
+From: Elizabeth Figura <zfigura@codeweavers.com>
Date: Fri, 5 Mar 2021 10:57:06 -0600
-Subject: [PATCH 02/34] winesync: Reserve a minor device number and ioctl
- range.
+Subject: [PATCH 02/32] ntsync: Reserve a minor device number and ioctl range.
---
Documentation/admin-guide/devices.txt | 3 ++-
Documentation/userspace-api/ioctl/ioctl-number.rst | 2 ++
- drivers/misc/winesync.c | 3 ++-
+ drivers/misc/ntsync.c | 3 ++-
include/linux/miscdevice.h | 1 +
4 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/Documentation/admin-guide/devices.txt b/Documentation/admin-guide/devices.txt
-index c07dc0ee860e..4e5abe508426 100644
+index 839054923530..13841636ce92 100644
--- a/Documentation/admin-guide/devices.txt
+++ b/Documentation/admin-guide/devices.txt
@@ -376,8 +376,9 @@
240 = /dev/userio Serio driver testing device
241 = /dev/vhost-vsock Host kernel driver for virtio vsock
242 = /dev/rfkill Turning off radio transmissions (rfkill)
-+ 243 = /dev/winesync Wine synchronization primitive device
++ 243 = /dev/ntsync NT synchronization primitive device
- 243-254 Reserved for local use
+ 244-254 Reserved for local use
@@ -147,86 +137,91 @@ index c07dc0ee860e..4e5abe508426 100644
11 char Raw keyboard device (Linux/SPARC only)
diff --git a/Documentation/userspace-api/ioctl/ioctl-number.rst b/Documentation/userspace-api/ioctl/ioctl-number.rst
-index 3b985b19f39d..3f313fd4338c 100644
+index 4ea5b837399a..055482769b35 100644
--- a/Documentation/userspace-api/ioctl/ioctl-number.rst
+++ b/Documentation/userspace-api/ioctl/ioctl-number.rst
@@ -375,6 +375,8 @@ Code Seq# Include File Comments
<mailto:thomas@winischhofer.net>
0xF6 all LTTng Linux Trace Toolkit Next Generation
<mailto:mathieu.desnoyers@efficios.com>
-+0xF7 00-0F uapi/linux/winesync.h Wine synchronization primitives
++0xF7 00-1F uapi/linux/ntsync.h NT synchronization primitives
+ <mailto:wine-devel@winehq.org>
0xF8 all arch/x86/include/uapi/asm/amd_hsmp.h AMD HSMP EPYC system management interface driver
<mailto:nchatrad@amd.com>
0xFD all linux/dm-ioctl.h
-diff --git a/drivers/misc/winesync.c b/drivers/misc/winesync.c
-index 111f33c5676e..85cb6ccaa077 100644
---- a/drivers/misc/winesync.c
-+++ b/drivers/misc/winesync.c
-@@ -40,7 +40,7 @@ static const struct file_operations winesync_fops = {
+diff --git a/drivers/misc/ntsync.c b/drivers/misc/ntsync.c
+index 9424c6210e51..84b498e2b2d5 100644
+--- a/drivers/misc/ntsync.c
++++ b/drivers/misc/ntsync.c
+@@ -40,7 +40,7 @@ static const struct file_operations ntsync_fops = {
};
- static struct miscdevice winesync_misc = {
+ static struct miscdevice ntsync_misc = {
- .minor = MISC_DYNAMIC_MINOR,
-+ .minor = WINESYNC_MINOR,
- .name = WINESYNC_NAME,
- .fops = &winesync_fops,
++ .minor = NTSYNC_MINOR,
+ .name = NTSYNC_NAME,
+ .fops = &ntsync_fops,
};
-@@ -62,3 +62,4 @@ MODULE_AUTHOR("Zebediah Figura");
- MODULE_DESCRIPTION("Kernel driver for Wine synchronization primitives");
+@@ -51,3 +51,4 @@ MODULE_AUTHOR("Elizabeth Figura");
+ MODULE_DESCRIPTION("Kernel driver for NT synchronization primitives");
MODULE_LICENSE("GPL");
- MODULE_ALIAS("devname:" WINESYNC_NAME);
-+MODULE_ALIAS_MISCDEV(WINESYNC_MINOR);
+ MODULE_ALIAS("devname:" NTSYNC_NAME);
++MODULE_ALIAS_MISCDEV(NTSYNC_MINOR);
diff --git a/include/linux/miscdevice.h b/include/linux/miscdevice.h
-index 0676f18093f9..350aecfcfb29 100644
+index c0fea6ca5076..fe5d9366fdf7 100644
--- a/include/linux/miscdevice.h
+++ b/include/linux/miscdevice.h
@@ -71,6 +71,7 @@
#define USERIO_MINOR 240
#define VHOST_VSOCK_MINOR 241
#define RFKILL_MINOR 242
-+#define WINESYNC_MINOR 243
++#define NTSYNC_MINOR 243
#define MISC_DYNAMIC_MINOR 255
struct device;
--
-2.36.0
+2.43.0
-From 8ad26f39cb5442d9e17f22ed0cda8d3669bb11b5 Mon Sep 17 00:00:00 2001
-From: Zebediah Figura <zfigura@codeweavers.com>
+From a5f6ffc3056884b48bb9161bc1246d841d9ed961 Mon Sep 17 00:00:00 2001
+From: Elizabeth Figura <zfigura@codeweavers.com>
Date: Fri, 5 Mar 2021 11:15:39 -0600
-Subject: [PATCH 03/34] winesync: Introduce WINESYNC_IOC_CREATE_SEM and
- WINESYNC_IOC_DELETE.
+Subject: [PATCH 03/32] ntsync: Introduce NTSYNC_IOC_CREATE_SEM and
+ NTSYNC_IOC_DELETE.
+These correspond to the NT syscalls NtCreateSemaphore() and NtClose().
+Unlike those functions, however, these ioctls do not handle object names, or
+lookup of existing objects, or handle reference counting, but simply create the
+underlying primitive. The user space emulator is expected to implement those
+functions if they are required.
---
- drivers/misc/winesync.c | 117 ++++++++++++++++++++++++++++++++++
- include/uapi/linux/winesync.h | 25 ++++++++
+ drivers/misc/ntsync.c | 117 ++++++++++++++++++++++++++++++++++++
+ include/uapi/linux/ntsync.h | 25 ++++++++
2 files changed, 142 insertions(+)
- create mode 100644 include/uapi/linux/winesync.h
+ create mode 100644 include/uapi/linux/ntsync.h
-diff --git a/drivers/misc/winesync.c b/drivers/misc/winesync.c
-index 85cb6ccaa077..36e31bbe0390 100644
---- a/drivers/misc/winesync.c
-+++ b/drivers/misc/winesync.c
+diff --git a/drivers/misc/ntsync.c b/drivers/misc/ntsync.c
+index 84b498e2b2d5..3287b94be351 100644
+--- a/drivers/misc/ntsync.c
++++ b/drivers/misc/ntsync.c
@@ -8,23 +8,140 @@
#include <linux/fs.h>
#include <linux/miscdevice.h>
#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/xarray.h>
-+#include <uapi/linux/winesync.h>
++#include <uapi/linux/ntsync.h>
- #define WINESYNC_NAME "winesync"
+ #define NTSYNC_NAME "ntsync"
-+enum winesync_type {
-+ WINESYNC_TYPE_SEM,
++enum ntsync_type {
++ NTSYNC_TYPE_SEM,
+};
+
-+struct winesync_obj {
++struct ntsync_obj {
+ struct rcu_head rhead;
+ struct kref refcount;
+
-+ enum winesync_type type;
++ enum ntsync_type type;
+
+ union {
+ struct {
@@ -236,25 +231,25 @@ index 85cb6ccaa077..36e31bbe0390 100644
+ } u;
+};
+
-+struct winesync_device {
++struct ntsync_device {
+ struct xarray objects;
+};
+
+static void destroy_obj(struct kref *ref)
+{
-+ struct winesync_obj *obj = container_of(ref, struct winesync_obj, refcount);
++ struct ntsync_obj *obj = container_of(ref, struct ntsync_obj, refcount);
+
+ kfree_rcu(obj, rhead);
+}
+
-+static void put_obj(struct winesync_obj *obj)
++static void put_obj(struct ntsync_obj *obj)
+{
+ kref_put(&obj->refcount, destroy_obj);
+}
+
- static int winesync_char_open(struct inode *inode, struct file *file)
+ static int ntsync_char_open(struct inode *inode, struct file *file)
{
-+ struct winesync_device *dev;
++ struct ntsync_device *dev;
+
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+ if (!dev)
@@ -266,10 +261,10 @@ index 85cb6ccaa077..36e31bbe0390 100644
return nonseekable_open(inode, file);
}
- static int winesync_char_release(struct inode *inode, struct file *file)
+ static int ntsync_char_release(struct inode *inode, struct file *file)
{
-+ struct winesync_device *dev = file->private_data;
-+ struct winesync_obj *obj;
++ struct ntsync_device *dev = file->private_data;
++ struct ntsync_obj *obj;
+ unsigned long id;
+
+ xa_for_each(&dev->objects, id, obj)
@@ -282,16 +277,16 @@ index 85cb6ccaa077..36e31bbe0390 100644
+ return 0;
+}
+
-+static void init_obj(struct winesync_obj *obj)
++static void init_obj(struct ntsync_obj *obj)
+{
+ kref_init(&obj->refcount);
+}
+
-+static int winesync_create_sem(struct winesync_device *dev, void __user *argp)
++static int ntsync_create_sem(struct ntsync_device *dev, void __user *argp)
+{
-+ struct winesync_sem_args __user *user_args = argp;
-+ struct winesync_sem_args args;
-+ struct winesync_obj *sem;
++ struct ntsync_sem_args __user *user_args = argp;
++ struct ntsync_sem_args args;
++ struct ntsync_obj *sem;
+ __u32 id;
+ int ret;
+
@@ -306,7 +301,7 @@ index 85cb6ccaa077..36e31bbe0390 100644
+ return -ENOMEM;
+
+ init_obj(sem);
-+ sem->type = WINESYNC_TYPE_SEM;
++ sem->type = NTSYNC_TYPE_SEM;
+ sem->u.sem.count = args.count;
+ sem->u.sem.max = args.max;
+
@@ -319,9 +314,9 @@ index 85cb6ccaa077..36e31bbe0390 100644
+ return put_user(id, &user_args->sem);
+}
+
-+static int winesync_delete(struct winesync_device *dev, void __user *argp)
++static int ntsync_delete(struct ntsync_device *dev, void __user *argp)
+{
-+ struct winesync_obj *obj;
++ struct ntsync_obj *obj;
+ __u32 id;
+
+ if (get_user(id, (__u32 __user *)argp))
@@ -335,87 +330,88 @@ index 85cb6ccaa077..36e31bbe0390 100644
return 0;
}
- static long winesync_char_ioctl(struct file *file, unsigned int cmd,
- unsigned long parm)
+ static long ntsync_char_ioctl(struct file *file, unsigned int cmd,
+ unsigned long parm)
{
-+ struct winesync_device *dev = file->private_data;
++ struct ntsync_device *dev = file->private_data;
+ void __user *argp = (void __user *)parm;
+
switch (cmd) {
-+ case WINESYNC_IOC_CREATE_SEM:
-+ return winesync_create_sem(dev, argp);
-+ case WINESYNC_IOC_DELETE:
-+ return winesync_delete(dev, argp);
++ case NTSYNC_IOC_CREATE_SEM:
++ return ntsync_create_sem(dev, argp);
++ case NTSYNC_IOC_DELETE:
++ return ntsync_delete(dev, argp);
default:
- return -ENOSYS;
+ return -ENOIOCTLCMD;
}
-diff --git a/include/uapi/linux/winesync.h b/include/uapi/linux/winesync.h
+diff --git a/include/uapi/linux/ntsync.h b/include/uapi/linux/ntsync.h
new file mode 100644
-index 000000000000..aabb491f39d2
+index 000000000000..d97afc138dcc
--- /dev/null
-+++ b/include/uapi/linux/winesync.h
++++ b/include/uapi/linux/ntsync.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+/*
-+ * Kernel support for Wine synchronization primitives
++ * Kernel support for NT synchronization primitive emulation
+ *
-+ * Copyright (C) 2021 Zebediah Figura
++ * Copyright (C) 2021-2022 Elizabeth Figura
+ */
+
-+#ifndef __LINUX_WINESYNC_H
-+#define __LINUX_WINESYNC_H
++#ifndef __LINUX_NTSYNC_H
++#define __LINUX_NTSYNC_H
+
+#include <linux/types.h>
+
-+struct winesync_sem_args {
++struct ntsync_sem_args {
+ __u32 sem;
+ __u32 count;
+ __u32 max;
+};
+
-+#define WINESYNC_IOC_BASE 0xf7
++#define NTSYNC_IOC_BASE 0xf7
+
-+#define WINESYNC_IOC_CREATE_SEM _IOWR(WINESYNC_IOC_BASE, 0, \
-+ struct winesync_sem_args)
-+#define WINESYNC_IOC_DELETE _IOW (WINESYNC_IOC_BASE, 1, __u32)
++#define NTSYNC_IOC_CREATE_SEM _IOWR(NTSYNC_IOC_BASE, 0, \
++ struct ntsync_sem_args)
++#define NTSYNC_IOC_DELETE _IOW (NTSYNC_IOC_BASE, 1, __u32)
+
+#endif
--
-2.36.0
+2.43.0
-From 144e223bfd7c5e733a9e7e50a3a8d37dbbedc0b7 Mon Sep 17 00:00:00 2001
-From: Zebediah Figura <zfigura@codeweavers.com>
+From 81b4a45e9f5ab9275e42e0edb6cbf6073c44d38e Mon Sep 17 00:00:00 2001
+From: Elizabeth Figura <zfigura@codeweavers.com>
Date: Fri, 5 Mar 2021 11:22:42 -0600
-Subject: [PATCH 04/34] winesync: Introduce WINESYNC_IOC_PUT_SEM.
+Subject: [PATCH 04/32] ntsync: Introduce NTSYNC_IOC_PUT_SEM.
+This corresponds to the NT syscall NtReleaseSemaphore().
---
- drivers/misc/winesync.c | 76 +++++++++++++++++++++++++++++++++++
- include/uapi/linux/winesync.h | 2 +
+ drivers/misc/ntsync.c | 76 +++++++++++++++++++++++++++++++++++++
+ include/uapi/linux/ntsync.h | 2 +
2 files changed, 78 insertions(+)
-diff --git a/drivers/misc/winesync.c b/drivers/misc/winesync.c
-index 36e31bbe0390..84b5a5c9e0ce 100644
---- a/drivers/misc/winesync.c
-+++ b/drivers/misc/winesync.c
-@@ -21,9 +21,11 @@ enum winesync_type {
- struct winesync_obj {
+diff --git a/drivers/misc/ntsync.c b/drivers/misc/ntsync.c
+index 3287b94be351..d1c91c2a4f1a 100644
+--- a/drivers/misc/ntsync.c
++++ b/drivers/misc/ntsync.c
+@@ -21,9 +21,11 @@ enum ntsync_type {
+ struct ntsync_obj {
struct rcu_head rhead;
struct kref refcount;
+ spinlock_t lock;
- enum winesync_type type;
+ enum ntsync_type type;
+ /* The following fields are protected by the object lock. */
union {
struct {
__u32 count;
-@@ -36,6 +38,19 @@ struct winesync_device {
+@@ -36,6 +38,19 @@ struct ntsync_device {
struct xarray objects;
};
-+static struct winesync_obj *get_obj(struct winesync_device *dev, __u32 id)
++static struct ntsync_obj *get_obj(struct ntsync_device *dev, __u32 id)
+{
-+ struct winesync_obj *obj;
++ struct ntsync_obj *obj;
+
+ rcu_read_lock();
+ obj = xa_load(&dev->objects, id);
@@ -428,15 +424,15 @@ index 36e31bbe0390..84b5a5c9e0ce 100644
+
static void destroy_obj(struct kref *ref)
{
- struct winesync_obj *obj = container_of(ref, struct winesync_obj, refcount);
-@@ -48,6 +63,18 @@ static void put_obj(struct winesync_obj *obj)
+ struct ntsync_obj *obj = container_of(ref, struct ntsync_obj, refcount);
+@@ -48,6 +63,18 @@ static void put_obj(struct ntsync_obj *obj)
kref_put(&obj->refcount, destroy_obj);
}
-+static struct winesync_obj *get_obj_typed(struct winesync_device *dev, __u32 id,
-+ enum winesync_type type)
++static struct ntsync_obj *get_obj_typed(struct ntsync_device *dev, __u32 id,
++ enum ntsync_type type)
+{
-+ struct winesync_obj *obj = get_obj(dev, id);
++ struct ntsync_obj *obj = get_obj(dev, id);
+
+ if (obj && obj->type != type) {
+ put_obj(obj);
@@ -445,18 +441,18 @@ index 36e31bbe0390..84b5a5c9e0ce 100644
+ return obj;
+}
+
- static int winesync_char_open(struct inode *inode, struct file *file)
+ static int ntsync_char_open(struct inode *inode, struct file *file)
{
- struct winesync_device *dev;
-@@ -81,6 +108,7 @@ static int winesync_char_release(struct inode *inode, struct file *file)
- static void init_obj(struct winesync_obj *obj)
+ struct ntsync_device *dev;
+@@ -81,6 +108,7 @@ static int ntsync_char_release(struct inode *inode, struct file *file)
+ static void init_obj(struct ntsync_obj *obj)
{
kref_init(&obj->refcount);
+ spin_lock_init(&obj->lock);
}
- static int winesync_create_sem(struct winesync_device *dev, void __user *argp)
-@@ -131,6 +159,52 @@ static int winesync_delete(struct winesync_device *dev, void __user *argp)
+ static int ntsync_create_sem(struct ntsync_device *dev, void __user *argp)
+@@ -131,6 +159,52 @@ static int ntsync_delete(struct ntsync_device *dev, void __user *argp)
return 0;
}
@@ -464,7 +460,7 @@ index 36e31bbe0390..84b5a5c9e0ce 100644
+ * Actually change the semaphore state, returning -EOVERFLOW if it is made
+ * invalid.
+ */
-+static int put_sem_state(struct winesync_obj *sem, __u32 count)
++static int put_sem_state(struct ntsync_obj *sem, __u32 count)
+{
+ lockdep_assert_held(&sem->lock);
+
@@ -476,18 +472,18 @@ index 36e31bbe0390..84b5a5c9e0ce 100644
+ return 0;
+}
+
-+static int winesync_put_sem(struct winesync_device *dev, void __user *argp)
++static int ntsync_put_sem(struct ntsync_device *dev, void __user *argp)
+{
-+ struct winesync_sem_args __user *user_args = argp;
-+ struct winesync_sem_args args;
-+ struct winesync_obj *sem;
++ struct ntsync_sem_args __user *user_args = argp;
++ struct ntsync_sem_args args;
++ struct ntsync_obj *sem;
+ __u32 prev_count;
+ int ret;
+
+ if (copy_from_user(&args, argp, sizeof(args)))
+ return -EFAULT;
+
-+ sem = get_obj_typed(dev, args.sem, WINESYNC_TYPE_SEM);
++ sem = get_obj_typed(dev, args.sem, NTSYNC_TYPE_SEM);
+ if (!sem)
+ return -EINVAL;
+
@@ -506,68 +502,72 @@ index 36e31bbe0390..84b5a5c9e0ce 100644
+ return ret;
+}
+
- static long winesync_char_ioctl(struct file *file, unsigned int cmd,
- unsigned long parm)
+ static long ntsync_char_ioctl(struct file *file, unsigned int cmd,
+ unsigned long parm)
{
-@@ -142,6 +216,8 @@ static long winesync_char_ioctl(struct file *file, unsigned int cmd,
- return winesync_create_sem(dev, argp);
- case WINESYNC_IOC_DELETE:
- return winesync_delete(dev, argp);
-+ case WINESYNC_IOC_PUT_SEM:
-+ return winesync_put_sem(dev, argp);
+@@ -142,6 +216,8 @@ static long ntsync_char_ioctl(struct file *file, unsigned int cmd,
+ return ntsync_create_sem(dev, argp);
+ case NTSYNC_IOC_DELETE:
+ return ntsync_delete(dev, argp);
++ case NTSYNC_IOC_PUT_SEM:
++ return ntsync_put_sem(dev, argp);
default:
- return -ENOSYS;
+ return -ENOIOCTLCMD;
}
-diff --git a/include/uapi/linux/winesync.h b/include/uapi/linux/winesync.h
-index aabb491f39d2..7681a168eb92 100644
---- a/include/uapi/linux/winesync.h
-+++ b/include/uapi/linux/winesync.h
-@@ -21,5 +21,7 @@ struct winesync_sem_args {
- #define WINESYNC_IOC_CREATE_SEM _IOWR(WINESYNC_IOC_BASE, 0, \
- struct winesync_sem_args)
- #define WINESYNC_IOC_DELETE _IOW (WINESYNC_IOC_BASE, 1, __u32)
-+#define WINESYNC_IOC_PUT_SEM _IOWR(WINESYNC_IOC_BASE, 2, \
-+ struct winesync_sem_args)
+diff --git a/include/uapi/linux/ntsync.h b/include/uapi/linux/ntsync.h
+index d97afc138dcc..8c610d65f8ef 100644
+--- a/include/uapi/linux/ntsync.h
++++ b/include/uapi/linux/ntsync.h
+@@ -21,5 +21,7 @@ struct ntsync_sem_args {
+ #define NTSYNC_IOC_CREATE_SEM _IOWR(NTSYNC_IOC_BASE, 0, \
+ struct ntsync_sem_args)
+ #define NTSYNC_IOC_DELETE _IOW (NTSYNC_IOC_BASE, 1, __u32)
++#define NTSYNC_IOC_PUT_SEM _IOWR(NTSYNC_IOC_BASE, 2, \
++ struct ntsync_sem_args)
#endif
--
-2.36.0
+2.43.0
-From 207daf2aa77f9d197b205a88322d5359f432bc67 Mon Sep 17 00:00:00 2001
-From: Zebediah Figura <zfigura@codeweavers.com>
+From 68f1adf9a8e440dcb00b6665b8bc0f8aee275857 Mon Sep 17 00:00:00 2001
+From: Elizabeth Figura <zfigura@codeweavers.com>
Date: Fri, 5 Mar 2021 11:31:44 -0600
-Subject: [PATCH 05/34] winesync: Introduce WINESYNC_IOC_WAIT_ANY.
+Subject: [PATCH 05/32] ntsync: Introduce NTSYNC_IOC_WAIT_ANY.
+This corresponds to part of the functionality of the NT syscall
+NtWaitForMultipleObjects(). Specifically, it implements the behaviour where
+the third argument (wait_any) is TRUE, and it does not handle alertable waits.
+Those features have been split out into separate patches to ease review.
---
- drivers/misc/winesync.c | 226 ++++++++++++++++++++++++++++++++++
- include/uapi/linux/winesync.h | 11 ++
- 2 files changed, 237 insertions(+)
+ drivers/misc/ntsync.c | 229 ++++++++++++++++++++++++++++++++++++
+ include/uapi/linux/ntsync.h | 13 ++
+ 2 files changed, 242 insertions(+)
-diff --git a/drivers/misc/winesync.c b/drivers/misc/winesync.c
-index 84b5a5c9e0ce..d9b5ab159520 100644
---- a/drivers/misc/winesync.c
-+++ b/drivers/misc/winesync.c
-@@ -23,6 +23,8 @@ struct winesync_obj {
+diff --git a/drivers/misc/ntsync.c b/drivers/misc/ntsync.c
+index d1c91c2a4f1a..2e8d3c2d51a4 100644
+--- a/drivers/misc/ntsync.c
++++ b/drivers/misc/ntsync.c
+@@ -23,6 +23,8 @@ struct ntsync_obj {
struct kref refcount;
spinlock_t lock;
+ struct list_head any_waiters;
+
- enum winesync_type type;
+ enum ntsync_type type;
/* The following fields are protected by the object lock. */
-@@ -34,6 +36,28 @@ struct winesync_obj {
+@@ -34,6 +36,28 @@ struct ntsync_obj {
} u;
};
-+struct winesync_q_entry {
++struct ntsync_q_entry {
+ struct list_head node;
-+ struct winesync_q *q;
-+ struct winesync_obj *obj;
++ struct ntsync_q *q;
++ struct ntsync_obj *obj;
+ __u32 index;
+};
+
-+struct winesync_q {
++struct ntsync_q {
+ struct task_struct *task;
+ __u32 owner;
+
@@ -579,27 +579,27 @@ index 84b5a5c9e0ce..d9b5ab159520 100644
+ atomic_t signaled;
+
+ __u32 count;
-+ struct winesync_q_entry entries[];
++ struct ntsync_q_entry entries[];
+};
+
- struct winesync_device {
+ struct ntsync_device {
struct xarray objects;
};
-@@ -109,6 +133,26 @@ static void init_obj(struct winesync_obj *obj)
+@@ -109,6 +133,26 @@ static void init_obj(struct ntsync_obj *obj)
{
kref_init(&obj->refcount);
spin_lock_init(&obj->lock);
+ INIT_LIST_HEAD(&obj->any_waiters);
+}
+
-+static void try_wake_any_sem(struct winesync_obj *sem)
++static void try_wake_any_sem(struct ntsync_obj *sem)
+{
-+ struct winesync_q_entry *entry;
++ struct ntsync_q_entry *entry;
+
+ lockdep_assert_held(&sem->lock);
+
+ list_for_each_entry(entry, &sem->any_waiters, node) {
-+ struct winesync_q *q = entry->q;
++ struct ntsync_q *q = entry->q;
+
+ if (!sem->u.sem.count)
+ break;
@@ -611,8 +611,8 @@ index 84b5a5c9e0ce..d9b5ab159520 100644
+ }
}
- static int winesync_create_sem(struct winesync_device *dev, void __user *argp)
-@@ -194,6 +238,8 @@ static int winesync_put_sem(struct winesync_device *dev, void __user *argp)
+ static int ntsync_create_sem(struct ntsync_device *dev, void __user *argp)
+@@ -194,6 +238,8 @@ static int ntsync_put_sem(struct ntsync_device *dev, void __user *argp)
prev_count = sem->u.sem.count;
ret = put_sem_state(sem, args.count);
@@ -621,11 +621,11 @@ index 84b5a5c9e0ce..d9b5ab159520 100644
spin_unlock(&sem->lock);
-@@ -205,6 +251,184 @@ static int winesync_put_sem(struct winesync_device *dev, void __user *argp)
+@@ -205,6 +251,187 @@ static int ntsync_put_sem(struct ntsync_device *dev, void __user *argp)
return ret;
}
-+static int winesync_schedule(const struct winesync_q *q, ktime_t *timeout)
++static int ntsync_schedule(const struct ntsync_q *q, ktime_t *timeout)
+{
+ int ret = 0;
+
@@ -648,15 +648,15 @@ index 84b5a5c9e0ce..d9b5ab159520 100644
+}
+
+/*
-+ * Allocate and initialize the winesync_q structure, but do not queue us yet.
++ * Allocate and initialize the ntsync_q structure, but do not queue us yet.
+ * Also, calculate the relative timeout.
+ */
-+static int setup_wait(struct winesync_device *dev,
-+ const struct winesync_wait_args *args,
-+ ktime_t *ret_timeout, struct winesync_q **ret_q)
++static int setup_wait(struct ntsync_device *dev,
++ const struct ntsync_wait_args *args,
++ ktime_t *ret_timeout, struct ntsync_q **ret_q)
+{
+ const __u32 count = args->count;
-+ struct winesync_q *q;
++ struct ntsync_q *q;
+ ktime_t timeout = 0;
+ __u32 *ids;
+ __u32 i, j;
@@ -664,6 +664,9 @@ index 84b5a5c9e0ce..d9b5ab159520 100644
+ if (!args->owner || args->pad)
+ return -EINVAL;
+
++ if (args->count > NTSYNC_MAX_WAIT_COUNT)
++ return -EINVAL;
++
+ if (args->timeout) {
+ struct timespec64 to;
+
@@ -695,8 +698,8 @@ index 84b5a5c9e0ce..d9b5ab159520 100644
+ q->count = count;
+
+ for (i = 0; i < count; i++) {
-+ struct winesync_q_entry *entry = &q->entries[i];
-+ struct winesync_obj *obj = get_obj(dev, ids[i]);
++ struct ntsync_q_entry *entry = &q->entries[i];
++ struct ntsync_obj *obj = get_obj(dev, ids[i]);
+
+ if (!obj)
+ goto err;
@@ -720,19 +723,19 @@ index 84b5a5c9e0ce..d9b5ab159520 100644
+ return -EINVAL;
+}
+
-+static void try_wake_any_obj(struct winesync_obj *obj)
++static void try_wake_any_obj(struct ntsync_obj *obj)
+{
+ switch (obj->type) {
-+ case WINESYNC_TYPE_SEM:
++ case NTSYNC_TYPE_SEM:
+ try_wake_any_sem(obj);
+ break;
+ }
+}
+
-+static int winesync_wait_any(struct winesync_device *dev, void __user *argp)
++static int ntsync_wait_any(struct ntsync_device *dev, void __user *argp)
+{
-+ struct winesync_wait_args args;
-+ struct winesync_q *q;
++ struct ntsync_wait_args args;
++ struct ntsync_q *q;
+ ktime_t timeout;
+ int signaled;
+ __u32 i;
@@ -748,8 +751,8 @@ index 84b5a5c9e0ce..d9b5ab159520 100644
+ /* queue ourselves */
+
+ for (i = 0; i < args.count; i++) {
-+ struct winesync_q_entry *entry = &q->entries[i];
-+ struct winesync_obj *obj = entry->obj;
++ struct ntsync_q_entry *entry = &q->entries[i];
++ struct ntsync_obj *obj = entry->obj;
+
+ spin_lock(&obj->lock);
+ list_add_tail(&entry->node, &obj->any_waiters);
@@ -759,7 +762,7 @@ index 84b5a5c9e0ce..d9b5ab159520 100644
+ /* check if we are already signaled */
+
+ for (i = 0; i < args.count; i++) {
-+ struct winesync_obj *obj = q->entries[i].obj;
++ struct ntsync_obj *obj = q->entries[i].obj;
+
+ if (atomic_read(&q->signaled) != -1)
+ break;
@@ -771,13 +774,13 @@ index 84b5a5c9e0ce..d9b5ab159520 100644
+
+ /* sleep */
+
-+ ret = winesync_schedule(q, args.timeout ? &timeout : NULL);
++ ret = ntsync_schedule(q, args.timeout ? &timeout : NULL);
+
+ /* and finally, unqueue */
+
+ for (i = 0; i < args.count; i++) {
-+ struct winesync_q_entry *entry = &q->entries[i];
-+ struct winesync_obj *obj = entry->obj;
++ struct ntsync_q_entry *entry = &q->entries[i];
++ struct ntsync_obj *obj = entry->obj;
+
+ spin_lock(&obj->lock);
+ list_del(&entry->node);
@@ -788,7 +791,7 @@ index 84b5a5c9e0ce..d9b5ab159520 100644
+
+ signaled = atomic_read(&q->signaled);
+ if (signaled != -1) {
-+ struct winesync_wait_args __user *user_args = argp;
++ struct ntsync_wait_args __user *user_args = argp;
+
+ /* even if we caught a signal, we need to communicate success */
+ ret = 0;
@@ -803,27 +806,27 @@ index 84b5a5c9e0ce..d9b5ab159520 100644
+ return ret;
+}
+
- static long winesync_char_ioctl(struct file *file, unsigned int cmd,
- unsigned long parm)
+ static long ntsync_char_ioctl(struct file *file, unsigned int cmd,
+ unsigned long parm)
{
-@@ -218,6 +442,8 @@ static long winesync_char_ioctl(struct file *file, unsigned int cmd,
- return winesync_delete(dev, argp);
- case WINESYNC_IOC_PUT_SEM:
- return winesync_put_sem(dev, argp);
-+ case WINESYNC_IOC_WAIT_ANY:
-+ return winesync_wait_any(dev, argp);
+@@ -218,6 +445,8 @@ static long ntsync_char_ioctl(struct file *file, unsigned int cmd,
+ return ntsync_delete(dev, argp);
+ case NTSYNC_IOC_PUT_SEM:
+ return ntsync_put_sem(dev, argp);
++ case NTSYNC_IOC_WAIT_ANY:
++ return ntsync_wait_any(dev, argp);
default:
- return -ENOSYS;
+ return -ENOIOCTLCMD;
}
-diff --git a/include/uapi/linux/winesync.h b/include/uapi/linux/winesync.h
-index 7681a168eb92..f57ebfbe1dd9 100644
---- a/include/uapi/linux/winesync.h
-+++ b/include/uapi/linux/winesync.h
-@@ -16,6 +16,15 @@ struct winesync_sem_args {
+diff --git a/include/uapi/linux/ntsync.h b/include/uapi/linux/ntsync.h
+index 8c610d65f8ef..10f07da7864e 100644
+--- a/include/uapi/linux/ntsync.h
++++ b/include/uapi/linux/ntsync.h
+@@ -16,6 +16,17 @@ struct ntsync_sem_args {
__u32 max;
};
-+struct winesync_wait_args {
++struct ntsync_wait_args {
+ __u64 timeout;
+ __u64 objs;
+ __u32 count;
@@ -832,35 +835,41 @@ index 7681a168eb92..f57ebfbe1dd9 100644
+ __u32 pad;
+};
+
- #define WINESYNC_IOC_BASE 0xf7
++#define NTSYNC_MAX_WAIT_COUNT 64
++
+ #define NTSYNC_IOC_BASE 0xf7
- #define WINESYNC_IOC_CREATE_SEM _IOWR(WINESYNC_IOC_BASE, 0, \
-@@ -23,5 +32,7 @@ struct winesync_sem_args {
- #define WINESYNC_IOC_DELETE _IOW (WINESYNC_IOC_BASE, 1, __u32)
- #define WINESYNC_IOC_PUT_SEM _IOWR(WINESYNC_IOC_BASE, 2, \
- struct winesync_sem_args)
-+#define WINESYNC_IOC_WAIT_ANY _IOWR(WINESYNC_IOC_BASE, 3, \
-+ struct winesync_wait_args)
+ #define NTSYNC_IOC_CREATE_SEM _IOWR(NTSYNC_IOC_BASE, 0, \
+@@ -23,5 +34,7 @@ struct ntsync_sem_args {
+ #define NTSYNC_IOC_DELETE _IOW (NTSYNC_IOC_BASE, 1, __u32)
+ #define NTSYNC_IOC_PUT_SEM _IOWR(NTSYNC_IOC_BASE, 2, \
+ struct ntsync_sem_args)
++#define NTSYNC_IOC_WAIT_ANY _IOWR(NTSYNC_IOC_BASE, 3, \
++ struct ntsync_wait_args)
#endif
--
-2.36.0
+2.43.0
-From 3d68ffb91767194d5a1a07aa6c57849343530a15 Mon Sep 17 00:00:00 2001
-From: Zebediah Figura <zfigura@codeweavers.com>
+From ec146c6daf3cd94d70135965f3260f2bea90f305 Mon Sep 17 00:00:00 2001
+From: Elizabeth Figura <zfigura@codeweavers.com>
Date: Fri, 5 Mar 2021 11:36:09 -0600
-Subject: [PATCH 06/34] winesync: Introduce WINESYNC_IOC_WAIT_ALL.
+Subject: [PATCH 06/32] ntsync: Introduce NTSYNC_IOC_WAIT_ALL.
+This corresponds to part of the functionality of the NT syscall
+NtWaitForMultipleObjects(). Specifically, it implements the behaviour where
+the third argument (wait_any) is FALSE, and it does not yet handle alertable
+waits.
---
- drivers/misc/winesync.c | 242 ++++++++++++++++++++++++++++++++--
- include/uapi/linux/winesync.h | 2 +
- 2 files changed, 236 insertions(+), 8 deletions(-)
+ drivers/misc/ntsync.c | 241 ++++++++++++++++++++++++++++++++++--
+ include/uapi/linux/ntsync.h | 2 +
+ 2 files changed, 235 insertions(+), 8 deletions(-)
-diff --git a/drivers/misc/winesync.c b/drivers/misc/winesync.c
-index d9b5ab159520..2b708c5b88a6 100644
---- a/drivers/misc/winesync.c
-+++ b/drivers/misc/winesync.c
-@@ -23,7 +23,34 @@ struct winesync_obj {
+diff --git a/drivers/misc/ntsync.c b/drivers/misc/ntsync.c
+index 2e8d3c2d51a4..2685363fae9e 100644
+--- a/drivers/misc/ntsync.c
++++ b/drivers/misc/ntsync.c
+@@ -23,7 +23,34 @@ struct ntsync_obj {
struct kref refcount;
spinlock_t lock;
@@ -893,18 +902,18 @@ index d9b5ab159520..2b708c5b88a6 100644
+ */
+ atomic_t all_hint;
- enum winesync_type type;
+ enum ntsync_type type;
-@@ -54,11 +81,25 @@ struct winesync_q {
+@@ -54,11 +81,25 @@ struct ntsync_q {
*/
atomic_t signaled;
+ bool all;
__u32 count;
- struct winesync_q_entry entries[];
+ struct ntsync_q_entry entries[];
};
- struct winesync_device {
+ struct ntsync_device {
+ /*
+ * Wait-all operations must atomically grab all objects, and be totally
+ * ordered with respect to each other and wait-any operations. If one
@@ -921,7 +930,7 @@ index d9b5ab159520..2b708c5b88a6 100644
struct xarray objects;
};
-@@ -107,6 +148,8 @@ static int winesync_char_open(struct inode *inode, struct file *file)
+@@ -107,6 +148,8 @@ static int ntsync_char_open(struct inode *inode, struct file *file)
if (!dev)
return -ENOMEM;
@@ -930,8 +939,8 @@ index d9b5ab159520..2b708c5b88a6 100644
xa_init_flags(&dev->objects, XA_FLAGS_ALLOC);
file->private_data = dev;
-@@ -132,8 +175,82 @@ static int winesync_char_release(struct inode *inode, struct file *file)
- static void init_obj(struct winesync_obj *obj)
+@@ -132,8 +175,81 @@ static int ntsync_char_release(struct inode *inode, struct file *file)
+ static void init_obj(struct ntsync_obj *obj)
{
kref_init(&obj->refcount);
+ atomic_set(&obj->all_hint, 0);
@@ -940,12 +949,12 @@ index d9b5ab159520..2b708c5b88a6 100644
+ INIT_LIST_HEAD(&obj->all_waiters);
+}
+
-+static bool is_signaled(struct winesync_obj *obj, __u32 owner)
++static bool is_signaled(struct ntsync_obj *obj, __u32 owner)
+{
+ lockdep_assert_held(&obj->lock);
+
+ switch (obj->type) {
-+ case WINESYNC_TYPE_SEM:
++ case NTSYNC_TYPE_SEM:
+ return !!obj->u.sem.count;
+ }
+
@@ -958,8 +967,8 @@ index d9b5ab159520..2b708c5b88a6 100644
+ * should not be locked again. This is necessary so that changing an object's
+ * state and waking it can be a single atomic operation.
+ */
-+static void try_wake_all(struct winesync_device *dev, struct winesync_q *q,
-+ struct winesync_obj *locked_obj)
++static void try_wake_all(struct ntsync_device *dev, struct ntsync_q *q,
++ struct ntsync_obj *locked_obj)
+{
+ __u32 count = q->count;
+ bool can_wake = true;
@@ -971,7 +980,7 @@ index d9b5ab159520..2b708c5b88a6 100644
+
+ for (i = 0; i < count; i++) {
+ if (q->entries[i].obj != locked_obj)
-+ spin_lock(&q->entries[i].obj->lock);
++ spin_lock_nest_lock(&q->entries[i].obj->lock, &dev->wait_all_lock);
+ }
+
+ for (i = 0; i < count; i++) {
@@ -983,10 +992,10 @@ index d9b5ab159520..2b708c5b88a6 100644
+
+ if (can_wake && atomic_cmpxchg(&q->signaled, -1, 0) == -1) {
+ for (i = 0; i < count; i++) {
-+ struct winesync_obj *obj = q->entries[i].obj;
++ struct ntsync_obj *obj = q->entries[i].obj;
+
+ switch (obj->type) {
-+ case WINESYNC_TYPE_SEM:
++ case NTSYNC_TYPE_SEM:
+ obj->u.sem.count--;
+ break;
+ }
@@ -1000,10 +1009,9 @@ index d9b5ab159520..2b708c5b88a6 100644
+ }
+}
+
-+static void try_wake_all_obj(struct winesync_device *dev,
-+ struct winesync_obj *obj)
++static void try_wake_all_obj(struct ntsync_device *dev, struct ntsync_obj *obj)
+{
-+ struct winesync_q_entry *entry;
++ struct ntsync_q_entry *entry;
+
+ lockdep_assert_held(&dev->wait_all_lock);
+ lockdep_assert_held(&obj->lock);
@@ -1012,15 +1020,15 @@ index d9b5ab159520..2b708c5b88a6 100644
+ try_wake_all(dev, entry->q, obj);
}
- static void try_wake_any_sem(struct winesync_obj *sem)
-@@ -234,14 +351,29 @@ static int winesync_put_sem(struct winesync_device *dev, void __user *argp)
+ static void try_wake_any_sem(struct ntsync_obj *sem)
+@@ -234,14 +350,29 @@ static int ntsync_put_sem(struct ntsync_device *dev, void __user *argp)
if (!sem)
return -EINVAL;
- spin_lock(&sem->lock);
+ if (atomic_read(&sem->all_hint) > 0) {
+ spin_lock(&dev->wait_all_lock);
-+ spin_lock(&sem->lock);
++ spin_lock_nest_lock(&sem->lock, &dev->wait_all_lock);
+
+ prev_count = sem->u.sem.count;
+ ret = put_sem_state(sem, args.count);
@@ -1049,16 +1057,16 @@ index d9b5ab159520..2b708c5b88a6 100644
put_obj(sem);
-@@ -278,7 +410,7 @@ static int winesync_schedule(const struct winesync_q *q, ktime_t *timeout)
+@@ -278,7 +409,7 @@ static int ntsync_schedule(const struct ntsync_q *q, ktime_t *timeout)
* Also, calculate the relative timeout.
*/
- static int setup_wait(struct winesync_device *dev,
-- const struct winesync_wait_args *args,
-+ const struct winesync_wait_args *args, bool all,
- ktime_t *ret_timeout, struct winesync_q **ret_q)
+ static int setup_wait(struct ntsync_device *dev,
+- const struct ntsync_wait_args *args,
++ const struct ntsync_wait_args *args, bool all,
+ ktime_t *ret_timeout, struct ntsync_q **ret_q)
{
const __u32 count = args->count;
-@@ -318,6 +450,7 @@ static int setup_wait(struct winesync_device *dev,
+@@ -321,6 +452,7 @@ static int setup_wait(struct ntsync_device *dev,
q->task = current;
q->owner = args->owner;
atomic_set(&q->signaled, -1);
@@ -1066,7 +1074,7 @@ index d9b5ab159520..2b708c5b88a6 100644
q->count = count;
for (i = 0; i < count; i++) {
-@@ -327,6 +460,16 @@ static int setup_wait(struct winesync_device *dev,
+@@ -330,6 +462,16 @@ static int setup_wait(struct ntsync_device *dev,
if (!obj)
goto err;
@@ -1083,7 +1091,7 @@ index d9b5ab159520..2b708c5b88a6 100644
entry->obj = obj;
entry->q = q;
entry->index = i;
-@@ -367,7 +510,7 @@ static int winesync_wait_any(struct winesync_device *dev, void __user *argp)
+@@ -370,7 +512,7 @@ static int ntsync_wait_any(struct ntsync_device *dev, void __user *argp)
if (copy_from_user(&args, argp, sizeof(args)))
return -EFAULT;
@@ -1092,14 +1100,14 @@ index d9b5ab159520..2b708c5b88a6 100644
if (ret < 0)
return ret;
-@@ -429,6 +572,87 @@ static int winesync_wait_any(struct winesync_device *dev, void __user *argp)
+@@ -432,6 +574,87 @@ static int ntsync_wait_any(struct ntsync_device *dev, void __user *argp)
return ret;
}
-+static int winesync_wait_all(struct winesync_device *dev, void __user *argp)
++static int ntsync_wait_all(struct ntsync_device *dev, void __user *argp)
+{
-+ struct winesync_wait_args args;
-+ struct winesync_q *q;
++ struct ntsync_wait_args args;
++ struct ntsync_q *q;
+ ktime_t timeout;
+ int signaled;
+ __u32 i;
@@ -1117,8 +1125,8 @@ index d9b5ab159520..2b708c5b88a6 100644
+ spin_lock(&dev->wait_all_lock);
+
+ for (i = 0; i < args.count; i++) {
-+ struct winesync_q_entry *entry = &q->entries[i];
-+ struct winesync_obj *obj = entry->obj;
++ struct ntsync_q_entry *entry = &q->entries[i];
++ struct ntsync_obj *obj = entry->obj;
+
+ atomic_inc(&obj->all_hint);
+
@@ -1137,15 +1145,15 @@ index d9b5ab159520..2b708c5b88a6 100644
+
+ /* sleep */
+
-+ ret = winesync_schedule(q, args.timeout ? &timeout : NULL);
++ ret = ntsync_schedule(q, args.timeout ? &timeout : NULL);
+
+ /* and finally, unqueue */
+
+ spin_lock(&dev->wait_all_lock);
+
+ for (i = 0; i < args.count; i++) {
-+ struct winesync_q_entry *entry = &q->entries[i];
-+ struct winesync_obj *obj = entry->obj;
++ struct ntsync_q_entry *entry = &q->entries[i];
++ struct ntsync_obj *obj = entry->obj;
+
+ /*
+ * obj->all_waiters is protected by dev->wait_all_lock rather
@@ -1162,7 +1170,7 @@ index d9b5ab159520..2b708c5b88a6 100644
+
+ signaled = atomic_read(&q->signaled);
+ if (signaled != -1) {
-+ struct winesync_wait_args __user *user_args = argp;
++ struct ntsync_wait_args __user *user_args = argp;
+
+ /* even if we caught a signal, we need to communicate success */
+ ret = 0;
@@ -1177,56 +1185,57 @@ index d9b5ab159520..2b708c5b88a6 100644
+ return ret;
+}
+
- static long winesync_char_ioctl(struct file *file, unsigned int cmd,
- unsigned long parm)
+ static long ntsync_char_ioctl(struct file *file, unsigned int cmd,
+ unsigned long parm)
{
-@@ -442,6 +666,8 @@ static long winesync_char_ioctl(struct file *file, unsigned int cmd,
- return winesync_delete(dev, argp);
- case WINESYNC_IOC_PUT_SEM:
- return winesync_put_sem(dev, argp);
-+ case WINESYNC_IOC_WAIT_ALL:
-+ return winesync_wait_all(dev, argp);
- case WINESYNC_IOC_WAIT_ANY:
- return winesync_wait_any(dev, argp);
+@@ -445,6 +668,8 @@ static long ntsync_char_ioctl(struct file *file, unsigned int cmd,
+ return ntsync_delete(dev, argp);
+ case NTSYNC_IOC_PUT_SEM:
+ return ntsync_put_sem(dev, argp);
++ case NTSYNC_IOC_WAIT_ALL:
++ return ntsync_wait_all(dev, argp);
+ case NTSYNC_IOC_WAIT_ANY:
+ return ntsync_wait_any(dev, argp);
default:
-diff --git a/include/uapi/linux/winesync.h b/include/uapi/linux/winesync.h
-index f57ebfbe1dd9..44025a510cb9 100644
---- a/include/uapi/linux/winesync.h
-+++ b/include/uapi/linux/winesync.h
-@@ -34,5 +34,7 @@ struct winesync_wait_args {
- struct winesync_sem_args)
- #define WINESYNC_IOC_WAIT_ANY _IOWR(WINESYNC_IOC_BASE, 3, \
- struct winesync_wait_args)
-+#define WINESYNC_IOC_WAIT_ALL _IOWR(WINESYNC_IOC_BASE, 4, \
-+ struct winesync_wait_args)
+diff --git a/include/uapi/linux/ntsync.h b/include/uapi/linux/ntsync.h
+index 10f07da7864e..a5bed5a39b21 100644
+--- a/include/uapi/linux/ntsync.h
++++ b/include/uapi/linux/ntsync.h
+@@ -36,5 +36,7 @@ struct ntsync_wait_args {
+ struct ntsync_sem_args)
+ #define NTSYNC_IOC_WAIT_ANY _IOWR(NTSYNC_IOC_BASE, 3, \
+ struct ntsync_wait_args)
++#define NTSYNC_IOC_WAIT_ALL _IOWR(NTSYNC_IOC_BASE, 4, \
++ struct ntsync_wait_args)
#endif
--
-2.36.0
+2.43.0
-From 2838a60302cd26a2ab92a143749e455edebe7b7c Mon Sep 17 00:00:00 2001
-From: Zebediah Figura <zfigura@codeweavers.com>
+From 965d8711ba4fbb0867c8baef95129f0ff62d9419 Mon Sep 17 00:00:00 2001
+From: Elizabeth Figura <zfigura@codeweavers.com>
Date: Fri, 5 Mar 2021 11:41:10 -0600
-Subject: [PATCH 07/34] winesync: Introduce WINESYNC_IOC_CREATE_MUTEX.
+Subject: [PATCH 07/32] ntsync: Introduce NTSYNC_IOC_CREATE_MUTEX.
+This corresponds to the NT syscall NtCreateMutant().
---
- drivers/misc/winesync.c | 72 +++++++++++++++++++++++++++++++++++
- include/uapi/linux/winesync.h | 8 ++++
+ drivers/misc/ntsync.c | 72 +++++++++++++++++++++++++++++++++++++
+ include/uapi/linux/ntsync.h | 8 +++++
2 files changed, 80 insertions(+)
-diff --git a/drivers/misc/winesync.c b/drivers/misc/winesync.c
-index 2b708c5b88a6..18eb05975907 100644
---- a/drivers/misc/winesync.c
-+++ b/drivers/misc/winesync.c
+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 winesync_type {
- WINESYNC_TYPE_SEM,
-+ WINESYNC_TYPE_MUTEX,
+ enum ntsync_type {
+ NTSYNC_TYPE_SEM,
++ NTSYNC_TYPE_MUTEX,
};
- struct winesync_obj {
-@@ -60,6 +61,10 @@ struct winesync_obj {
+ struct ntsync_obj {
+@@ -60,6 +61,10 @@ struct ntsync_obj {
__u32 count;
__u32 max;
} sem;
@@ -1237,40 +1246,40 @@ index 2b708c5b88a6..18eb05975907 100644
} u;
};
-@@ -188,6 +193,10 @@ static bool is_signaled(struct winesync_obj *obj, __u32 owner)
+@@ -188,6 +193,10 @@ static bool is_signaled(struct ntsync_obj *obj, __u32 owner)
switch (obj->type) {
- case WINESYNC_TYPE_SEM:
+ case NTSYNC_TYPE_SEM:
return !!obj->u.sem.count;
-+ case WINESYNC_TYPE_MUTEX:
++ 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 winesync_device *dev, struct winesync_q *q,
- case WINESYNC_TYPE_SEM:
+@@ -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 WINESYNC_TYPE_MUTEX:
++ case NTSYNC_TYPE_MUTEX:
+ obj->u.mutex.count++;
+ obj->u.mutex.owner = q->owner;
+ break;
}
}
wake_up_process(q->task);
-@@ -272,6 +285,28 @@ static void try_wake_any_sem(struct winesync_obj *sem)
+@@ -271,6 +284,28 @@ static void try_wake_any_sem(struct ntsync_obj *sem)
}
}
-+static void try_wake_any_mutex(struct winesync_obj *mutex)
++static void try_wake_any_mutex(struct ntsync_obj *mutex)
+{
-+ struct winesync_q_entry *entry;
++ struct ntsync_q_entry *entry;
+
+ lockdep_assert_held(&mutex->lock);
+
+ list_for_each_entry(entry, &mutex->any_waiters, node) {
-+ struct winesync_q *q = entry->q;
++ struct ntsync_q *q = entry->q;
+
+ if (mutex->u.mutex.count == UINT_MAX)
+ break;
@@ -1285,18 +1294,18 @@ index 2b708c5b88a6..18eb05975907 100644
+ }
+}
+
- static int winesync_create_sem(struct winesync_device *dev, void __user *argp)
+ static int ntsync_create_sem(struct ntsync_device *dev, void __user *argp)
{
- struct winesync_sem_args __user *user_args = argp;
-@@ -304,6 +339,38 @@ static int winesync_create_sem(struct winesync_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 winesync_create_mutex(struct winesync_device *dev, void __user *argp)
++static int ntsync_create_mutex(struct ntsync_device *dev, void __user *argp)
+{
-+ struct winesync_mutex_args __user *user_args = argp;
-+ struct winesync_mutex_args args;
-+ struct winesync_obj *mutex;
++ struct ntsync_mutex_args __user *user_args = argp;
++ struct ntsync_mutex_args args;
++ struct ntsync_obj *mutex;
+ __u32 id;
+ int ret;
+
@@ -1311,7 +1320,7 @@ index 2b708c5b88a6..18eb05975907 100644
+ return -ENOMEM;
+
+ init_obj(mutex);
-+ mutex->type = WINESYNC_TYPE_MUTEX;
++ mutex->type = NTSYNC_TYPE_MUTEX;
+ mutex->u.mutex.count = args.count;
+ mutex->u.mutex.owner = args.owner;
+
@@ -1324,79 +1333,80 @@ index 2b708c5b88a6..18eb05975907 100644
+ return put_user(id, &user_args->mutex);
+}
+
- static int winesync_delete(struct winesync_device *dev, void __user *argp)
+ static int ntsync_delete(struct ntsync_device *dev, void __user *argp)
{
- struct winesync_obj *obj;
-@@ -495,6 +562,9 @@ static void try_wake_any_obj(struct winesync_obj *obj)
- case WINESYNC_TYPE_SEM:
+ 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 WINESYNC_TYPE_MUTEX:
++ case NTSYNC_TYPE_MUTEX:
+ try_wake_any_mutex(obj);
+ break;
}
}
-@@ -660,6 +730,8 @@ static long winesync_char_ioctl(struct file *file, unsigned int cmd,
+@@ -662,6 +732,8 @@ static long ntsync_char_ioctl(struct file *file, unsigned int cmd,
void __user *argp = (void __user *)parm;
switch (cmd) {
-+ case WINESYNC_IOC_CREATE_MUTEX:
-+ return winesync_create_mutex(dev, argp);
- case WINESYNC_IOC_CREATE_SEM:
- return winesync_create_sem(dev, argp);
- case WINESYNC_IOC_DELETE:
-diff --git a/include/uapi/linux/winesync.h b/include/uapi/linux/winesync.h
-index 44025a510cb9..23606a3b1546 100644
---- a/include/uapi/linux/winesync.h
-+++ b/include/uapi/linux/winesync.h
-@@ -16,6 +16,12 @@ struct winesync_sem_args {
++ 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 winesync_mutex_args {
++struct ntsync_mutex_args {
+ __u32 mutex;
+ __u32 owner;
+ __u32 count;
+};
+
- struct winesync_wait_args {
+ struct ntsync_wait_args {
__u64 timeout;
__u64 objs;
-@@ -36,5 +42,7 @@ struct winesync_wait_args {
- struct winesync_wait_args)
- #define WINESYNC_IOC_WAIT_ALL _IOWR(WINESYNC_IOC_BASE, 4, \
- struct winesync_wait_args)
-+#define WINESYNC_IOC_CREATE_MUTEX _IOWR(WINESYNC_IOC_BASE, 5, \
-+ struct winesync_mutex_args)
+@@ -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.36.0
+2.43.0
-From 25b9628ad91377840cdc2b08dd53e1539ad05bdd Mon Sep 17 00:00:00 2001
-From: Zebediah Figura <zfigura@codeweavers.com>
+From b348f2e4e4054c20f0f1852ffaa90095e1f32415 Mon Sep 17 00:00:00 2001
+From: Elizabeth Figura <zfigura@codeweavers.com>
Date: Fri, 5 Mar 2021 11:44:41 -0600
-Subject: [PATCH 08/34] winesync: Introduce WINESYNC_IOC_PUT_MUTEX.
+Subject: [PATCH 08/32] ntsync: Introduce NTSYNC_IOC_PUT_MUTEX.
+This corresponds to the NT syscall NtReleaseMutant().
---
- drivers/misc/winesync.c | 67 +++++++++++++++++++++++++++++++++++
- include/uapi/linux/winesync.h | 2 ++
+ drivers/misc/ntsync.c | 67 +++++++++++++++++++++++++++++++++++++
+ include/uapi/linux/ntsync.h | 2 ++
2 files changed, 69 insertions(+)
-diff --git a/drivers/misc/winesync.c b/drivers/misc/winesync.c
-index 18eb05975907..d18d08a68546 100644
---- a/drivers/misc/winesync.c
-+++ b/drivers/misc/winesync.c
-@@ -450,6 +450,71 @@ static int winesync_put_sem(struct winesync_device *dev, void __user *argp)
+diff --git a/drivers/misc/ntsync.c b/drivers/misc/ntsync.c
+index d48f2ef41341..28f43768d1c3 100644
+--- a/drivers/misc/ntsync.c
++++ b/drivers/misc/ntsync.c
+@@ -449,6 +449,71 @@ static int ntsync_put_sem(struct ntsync_device *dev, void __user *argp)
return ret;
}
+/*
+ * Actually change the mutex state, returning -EPERM if not the owner.
+ */
-+static int put_mutex_state(struct winesync_obj *mutex,
-+ const struct winesync_mutex_args *args)
++static int put_mutex_state(struct ntsync_obj *mutex,
++ const struct ntsync_mutex_args *args)
+{
+ lockdep_assert_held(&mutex->lock);
+
@@ -1408,11 +1418,11 @@ index 18eb05975907..d18d08a68546 100644
+ return 0;
+}
+
-+static int winesync_put_mutex(struct winesync_device *dev, void __user *argp)
++static int ntsync_put_mutex(struct ntsync_device *dev, void __user *argp)
+{
-+ struct winesync_mutex_args __user *user_args = argp;
-+ struct winesync_mutex_args args;
-+ struct winesync_obj *mutex;
++ struct ntsync_mutex_args __user *user_args = argp;
++ struct ntsync_mutex_args args;
++ struct ntsync_obj *mutex;
+ __u32 prev_count;
+ int ret;
+
@@ -1421,13 +1431,13 @@ index 18eb05975907..d18d08a68546 100644
+ if (!args.owner)
+ return -EINVAL;
+
-+ mutex = get_obj_typed(dev, args.mutex, WINESYNC_TYPE_MUTEX);
++ mutex = get_obj_typed(dev, args.mutex, NTSYNC_TYPE_MUTEX);
+ if (!mutex)
+ return -EINVAL;
+
+ if (atomic_read(&mutex->all_hint) > 0) {
+ spin_lock(&dev->wait_all_lock);
-+ spin_lock(&mutex->lock);
++ spin_lock_nest_lock(&mutex->lock, &dev->wait_all_lock);
+
+ prev_count = mutex->u.mutex.count;
+ ret = put_mutex_state(mutex, &args);
@@ -1457,48 +1467,51 @@ index 18eb05975907..d18d08a68546 100644
+ return ret;
+}
+
- static int winesync_schedule(const struct winesync_q *q, ktime_t *timeout)
+ static int ntsync_schedule(const struct ntsync_q *q, ktime_t *timeout)
{
int ret = 0;
-@@ -736,6 +801,8 @@ static long winesync_char_ioctl(struct file *file, unsigned int cmd,
- return winesync_create_sem(dev, argp);
- case WINESYNC_IOC_DELETE:
- return winesync_delete(dev, argp);
-+ case WINESYNC_IOC_PUT_MUTEX:
-+ return winesync_put_mutex(dev, argp);
- case WINESYNC_IOC_PUT_SEM:
- return winesync_put_sem(dev, argp);
- case WINESYNC_IOC_WAIT_ALL:
-diff --git a/include/uapi/linux/winesync.h b/include/uapi/linux/winesync.h
-index 23606a3b1546..fde08cb8ab95 100644
---- a/include/uapi/linux/winesync.h
-+++ b/include/uapi/linux/winesync.h
-@@ -44,5 +44,7 @@ struct winesync_wait_args {
- struct winesync_wait_args)
- #define WINESYNC_IOC_CREATE_MUTEX _IOWR(WINESYNC_IOC_BASE, 5, \
- struct winesync_mutex_args)
-+#define WINESYNC_IOC_PUT_MUTEX _IOWR(WINESYNC_IOC_BASE, 6, \
-+ struct winesync_mutex_args)
+@@ -738,6 +803,8 @@ static long ntsync_char_ioctl(struct file *file, unsigned int cmd,
+ return ntsync_create_sem(dev, argp);
+ case NTSYNC_IOC_DELETE:
+ return ntsync_delete(dev, argp);
++ case NTSYNC_IOC_PUT_MUTEX:
++ return ntsync_put_mutex(dev, argp);
+ case NTSYNC_IOC_PUT_SEM:
+ return ntsync_put_sem(dev, argp);
+ case NTSYNC_IOC_WAIT_ALL:
+diff --git a/include/uapi/linux/ntsync.h b/include/uapi/linux/ntsync.h
+index 26d1b3d4847f..2e44e7e77776 100644
+--- a/include/uapi/linux/ntsync.h
++++ b/include/uapi/linux/ntsync.h
+@@ -46,5 +46,7 @@ struct ntsync_wait_args {
+ struct ntsync_wait_args)
+ #define NTSYNC_IOC_CREATE_MUTEX _IOWR(NTSYNC_IOC_BASE, 5, \
+ struct ntsync_mutex_args)
++#define NTSYNC_IOC_PUT_MUTEX _IOWR(NTSYNC_IOC_BASE, 6, \
++ struct ntsync_mutex_args)
#endif
--
-2.36.0
+2.43.0
-From 97d6dc0155da6609849e6a03bcc9e7d7e0cb58f5 Mon Sep 17 00:00:00 2001
-From: Zebediah Figura <zfigura@codeweavers.com>
+From f042ca07e1744d2bb04942163e4e65fc6e624f41 Mon Sep 17 00:00:00 2001
+From: Elizabeth Figura <zfigura@codeweavers.com>
Date: Fri, 5 Mar 2021 11:46:46 -0600
-Subject: [PATCH 09/34] winesync: Introduce WINESYNC_IOC_KILL_OWNER.
+Subject: [PATCH 09/32] ntsync: Introduce NTSYNC_IOC_KILL_OWNER.
+This does not correspond to any NT syscall, but rather should be called by the
+user-space NT emulator when a thread dies. It is responsible for marking any
+mutexes owned by that thread as abandoned.
---
- drivers/misc/winesync.c | 80 ++++++++++++++++++++++++++++++++++-
- include/uapi/linux/winesync.h | 1 +
+ drivers/misc/ntsync.c | 80 ++++++++++++++++++++++++++++++++++++-
+ include/uapi/linux/ntsync.h | 1 +
2 files changed, 79 insertions(+), 2 deletions(-)
-diff --git a/drivers/misc/winesync.c b/drivers/misc/winesync.c
-index d18d08a68546..891537063bb6 100644
---- a/drivers/misc/winesync.c
-+++ b/drivers/misc/winesync.c
-@@ -64,6 +64,7 @@ struct winesync_obj {
+diff --git a/drivers/misc/ntsync.c b/drivers/misc/ntsync.c
+index 28f43768d1c3..1173c750c106 100644
+--- a/drivers/misc/ntsync.c
++++ b/drivers/misc/ntsync.c
+@@ -64,6 +64,7 @@ struct ntsync_obj {
struct {
__u32 count;
__u32 owner;
@@ -1506,25 +1519,25 @@ index d18d08a68546..891537063bb6 100644
} mutex;
} u;
};
-@@ -87,6 +88,7 @@ struct winesync_q {
+@@ -87,6 +88,7 @@ struct ntsync_q {
atomic_t signaled;
bool all;
+ bool ownerdead;
__u32 count;
- struct winesync_q_entry entries[];
+ struct ntsync_q_entry entries[];
};
-@@ -240,6 +242,9 @@ static void try_wake_all(struct winesync_device *dev, struct winesync_q *q,
+@@ -240,6 +242,9 @@ static void try_wake_all(struct ntsync_device *dev, struct ntsync_q *q,
obj->u.sem.count--;
break;
- case WINESYNC_TYPE_MUTEX:
+ case NTSYNC_TYPE_MUTEX:
+ if (obj->u.mutex.ownerdead)
+ q->ownerdead = true;
+ obj->u.mutex.ownerdead = false;
obj->u.mutex.count++;
obj->u.mutex.owner = q->owner;
break;
-@@ -300,6 +305,9 @@ static void try_wake_any_mutex(struct winesync_obj *mutex)
+@@ -299,6 +304,9 @@ static void try_wake_any_mutex(struct ntsync_obj *mutex)
continue;
if (atomic_cmpxchg(&q->signaled, -1, entry->index) == -1) {
@@ -1534,14 +1547,14 @@ index d18d08a68546..891537063bb6 100644
mutex->u.mutex.count++;
mutex->u.mutex.owner = q->owner;
wake_up_process(q->task);
-@@ -515,6 +523,71 @@ static int winesync_put_mutex(struct winesync_device *dev, void __user *argp)
+@@ -514,6 +522,71 @@ static int ntsync_put_mutex(struct ntsync_device *dev, void __user *argp)
return ret;
}
+/*
+ * Actually change the mutex state to mark its owner as dead.
+ */
-+static void put_mutex_ownerdead_state(struct winesync_obj *mutex)
++static void put_mutex_ownerdead_state(struct ntsync_obj *mutex)
+{
+ lockdep_assert_held(&mutex->lock);
+
@@ -1550,9 +1563,9 @@ index d18d08a68546..891537063bb6 100644
+ mutex->u.mutex.count = 0;
+}
+
-+static int winesync_kill_owner(struct winesync_device *dev, void __user *argp)
++static int ntsync_kill_owner(struct ntsync_device *dev, void __user *argp)
+{
-+ struct winesync_obj *obj;
++ struct ntsync_obj *obj;
+ unsigned long id;
+ __u32 owner;
+
@@ -1567,14 +1580,14 @@ index d18d08a68546..891537063bb6 100644
+ if (!kref_get_unless_zero(&obj->refcount))
+ continue;
+
-+ if (obj->type != WINESYNC_TYPE_MUTEX) {
++ if (obj->type != NTSYNC_TYPE_MUTEX) {
+ put_obj(obj);
+ continue;
+ }
+
+ if (atomic_read(&obj->all_hint) > 0) {
+ spin_lock(&dev->wait_all_lock);
-+ spin_lock(&obj->lock);
++ spin_lock_nest_lock(&obj->lock, &dev->wait_all_lock);
+
+ if (obj->u.mutex.owner == owner) {
+ put_mutex_ownerdead_state(obj);
@@ -1603,10 +1616,10 @@ index d18d08a68546..891537063bb6 100644
+ return 0;
+}
+
- static int winesync_schedule(const struct winesync_q *q, ktime_t *timeout)
+ static int ntsync_schedule(const struct ntsync_q *q, ktime_t *timeout)
{
int ret = 0;
-@@ -583,6 +656,7 @@ static int setup_wait(struct winesync_device *dev,
+@@ -585,6 +658,7 @@ static int setup_wait(struct ntsync_device *dev,
q->owner = args->owner;
atomic_set(&q->signaled, -1);
q->all = all;
@@ -1614,8 +1627,8 @@ index d18d08a68546..891537063bb6 100644
q->count = count;
for (i = 0; i < count; i++) {
-@@ -695,7 +769,7 @@ static int winesync_wait_any(struct winesync_device *dev, void __user *argp)
- struct winesync_wait_args __user *user_args = argp;
+@@ -697,7 +771,7 @@ static int ntsync_wait_any(struct ntsync_device *dev, void __user *argp)
+ struct ntsync_wait_args __user *user_args = argp;
/* even if we caught a signal, we need to communicate success */
- ret = 0;
@@ -1623,8 +1636,8 @@ index d18d08a68546..891537063bb6 100644
if (put_user(signaled, &user_args->index))
ret = -EFAULT;
-@@ -776,7 +850,7 @@ static int winesync_wait_all(struct winesync_device *dev, void __user *argp)
- struct winesync_wait_args __user *user_args = argp;
+@@ -778,7 +852,7 @@ static int ntsync_wait_all(struct ntsync_device *dev, void __user *argp)
+ struct ntsync_wait_args __user *user_args = argp;
/* even if we caught a signal, we need to communicate success */
- ret = 0;
@@ -1632,58 +1645,59 @@ index d18d08a68546..891537063bb6 100644
if (put_user(signaled, &user_args->index))
ret = -EFAULT;
-@@ -801,6 +875,8 @@ static long winesync_char_ioctl(struct file *file, unsigned int cmd,
- return winesync_create_sem(dev, argp);
- case WINESYNC_IOC_DELETE:
- return winesync_delete(dev, argp);
-+ case WINESYNC_IOC_KILL_OWNER:
-+ return winesync_kill_owner(dev, argp);
- case WINESYNC_IOC_PUT_MUTEX:
- return winesync_put_mutex(dev, argp);
- case WINESYNC_IOC_PUT_SEM:
-diff --git a/include/uapi/linux/winesync.h b/include/uapi/linux/winesync.h
-index fde08cb8ab95..f57aa76d57f5 100644
---- a/include/uapi/linux/winesync.h
-+++ b/include/uapi/linux/winesync.h
-@@ -46,5 +46,6 @@ struct winesync_wait_args {
- struct winesync_mutex_args)
- #define WINESYNC_IOC_PUT_MUTEX _IOWR(WINESYNC_IOC_BASE, 6, \
- struct winesync_mutex_args)
-+#define WINESYNC_IOC_KILL_OWNER _IOW (WINESYNC_IOC_BASE, 7, __u32)
+@@ -803,6 +877,8 @@ static long ntsync_char_ioctl(struct file *file, unsigned int cmd,
+ return ntsync_create_sem(dev, argp);
+ case NTSYNC_IOC_DELETE:
+ return ntsync_delete(dev, argp);
++ case NTSYNC_IOC_KILL_OWNER:
++ return ntsync_kill_owner(dev, argp);
+ case NTSYNC_IOC_PUT_MUTEX:
+ return ntsync_put_mutex(dev, argp);
+ case NTSYNC_IOC_PUT_SEM:
+diff --git a/include/uapi/linux/ntsync.h b/include/uapi/linux/ntsync.h
+index 2e44e7e77776..fec9a3993322 100644
+--- a/include/uapi/linux/ntsync.h
++++ b/include/uapi/linux/ntsync.h
+@@ -48,5 +48,6 @@ struct ntsync_wait_args {
+ struct ntsync_mutex_args)
+ #define NTSYNC_IOC_PUT_MUTEX _IOWR(NTSYNC_IOC_BASE, 6, \
+ struct ntsync_mutex_args)
++#define NTSYNC_IOC_KILL_OWNER _IOW (NTSYNC_IOC_BASE, 7, __u32)
#endif
--
-2.36.0
+2.43.0
-From 888bb6fa10b7eb593db18a38fe696fc396ee30de Mon Sep 17 00:00:00 2001
-From: Zebediah Figura <zfigura@codeweavers.com>
+From fc85bff90ef0348584fca122f96aa3ec1a5fe604 Mon Sep 17 00:00:00 2001
+From: Elizabeth Figura <zfigura@codeweavers.com>
Date: Fri, 5 Mar 2021 11:47:55 -0600
-Subject: [PATCH 10/34] winesync: Introduce WINESYNC_IOC_READ_SEM.
+Subject: [PATCH 10/32] ntsync: Introduce NTSYNC_IOC_READ_SEM.
+This corresponds to the NT syscall NtQuerySemaphore().
---
- drivers/misc/winesync.c | 29 +++++++++++++++++++++++++++++
- include/uapi/linux/winesync.h | 2 ++
+ drivers/misc/ntsync.c | 29 +++++++++++++++++++++++++++++
+ include/uapi/linux/ntsync.h | 2 ++
2 files changed, 31 insertions(+)
-diff --git a/drivers/misc/winesync.c b/drivers/misc/winesync.c
-index 891537063bb6..98bedda2f8eb 100644
---- a/drivers/misc/winesync.c
-+++ b/drivers/misc/winesync.c
-@@ -523,6 +523,33 @@ static int winesync_put_mutex(struct winesync_device *dev, void __user *argp)
+diff --git a/drivers/misc/ntsync.c b/drivers/misc/ntsync.c
+index 1173c750c106..70c60f294bb2 100644
+--- a/drivers/misc/ntsync.c
++++ b/drivers/misc/ntsync.c
+@@ -522,6 +522,33 @@ static int ntsync_put_mutex(struct ntsync_device *dev, void __user *argp)
return ret;
}
-+static int winesync_read_sem(struct winesync_device *dev, void __user *argp)
++static int ntsync_read_sem(struct ntsync_device *dev, void __user *argp)
+{
-+ struct winesync_sem_args __user *user_args = argp;
-+ struct winesync_sem_args args;
-+ struct winesync_obj *sem;
++ struct ntsync_sem_args __user *user_args = argp;
++ struct ntsync_sem_args args;
++ struct ntsync_obj *sem;
+ __u32 id;
+
+ if (get_user(id, &user_args->sem))
+ return -EFAULT;
+
-+ sem = get_obj_typed(dev, id, WINESYNC_TYPE_SEM);
++ sem = get_obj_typed(dev, id, NTSYNC_TYPE_SEM);
+ if (!sem)
+ return -EINVAL;
+
@@ -1703,60 +1717,61 @@ index 891537063bb6..98bedda2f8eb 100644
/*
* Actually change the mutex state to mark its owner as dead.
*/
-@@ -881,6 +908,8 @@ static long winesync_char_ioctl(struct file *file, unsigned int cmd,
- return winesync_put_mutex(dev, argp);
- case WINESYNC_IOC_PUT_SEM:
- return winesync_put_sem(dev, argp);
-+ case WINESYNC_IOC_READ_SEM:
-+ return winesync_read_sem(dev, argp);
- case WINESYNC_IOC_WAIT_ALL:
- return winesync_wait_all(dev, argp);
- case WINESYNC_IOC_WAIT_ANY:
-diff --git a/include/uapi/linux/winesync.h b/include/uapi/linux/winesync.h
-index f57aa76d57f5..311eb810647d 100644
---- a/include/uapi/linux/winesync.h
-+++ b/include/uapi/linux/winesync.h
-@@ -47,5 +47,7 @@ struct winesync_wait_args {
- #define WINESYNC_IOC_PUT_MUTEX _IOWR(WINESYNC_IOC_BASE, 6, \
- struct winesync_mutex_args)
- #define WINESYNC_IOC_KILL_OWNER _IOW (WINESYNC_IOC_BASE, 7, __u32)
-+#define WINESYNC_IOC_READ_SEM _IOWR(WINESYNC_IOC_BASE, 8, \
-+ struct winesync_sem_args)
+@@ -883,6 +910,8 @@ static long ntsync_char_ioctl(struct file *file, unsigned int cmd,
+ return ntsync_put_mutex(dev, argp);
+ case NTSYNC_IOC_PUT_SEM:
+ return ntsync_put_sem(dev, argp);
++ case NTSYNC_IOC_READ_SEM:
++ return ntsync_read_sem(dev, argp);
+ case NTSYNC_IOC_WAIT_ALL:
+ return ntsync_wait_all(dev, argp);
+ case NTSYNC_IOC_WAIT_ANY:
+diff --git a/include/uapi/linux/ntsync.h b/include/uapi/linux/ntsync.h
+index fec9a3993322..b84a57c13d80 100644
+--- a/include/uapi/linux/ntsync.h
++++ b/include/uapi/linux/ntsync.h
+@@ -49,5 +49,7 @@ struct ntsync_wait_args {
+ #define NTSYNC_IOC_PUT_MUTEX _IOWR(NTSYNC_IOC_BASE, 6, \
+ struct ntsync_mutex_args)
+ #define NTSYNC_IOC_KILL_OWNER _IOW (NTSYNC_IOC_BASE, 7, __u32)
++#define NTSYNC_IOC_READ_SEM _IOWR(NTSYNC_IOC_BASE, 8, \
++ struct ntsync_sem_args)
#endif
--
-2.36.0
+2.43.0
-From 4f17c2ab7b9aca22fb00f7f16e0bd3cf70c44fe1 Mon Sep 17 00:00:00 2001
-From: Zebediah Figura <zfigura@codeweavers.com>
+From 4acc2acbbcacf80485e7d443c0a2327d50879c64 Mon Sep 17 00:00:00 2001
+From: Elizabeth Figura <zfigura@codeweavers.com>
Date: Fri, 5 Mar 2021 11:48:10 -0600
-Subject: [PATCH 11/34] winesync: Introduce WINESYNC_IOC_READ_MUTEX.
+Subject: [PATCH 11/32] ntsync: Introduce NTSYNC_IOC_READ_MUTEX.
+This corresponds to the NT syscall NtQueryMutant().
---
- drivers/misc/winesync.c | 31 +++++++++++++++++++++++++++++++
- include/uapi/linux/winesync.h | 2 ++
+ drivers/misc/ntsync.c | 31 +++++++++++++++++++++++++++++++
+ include/uapi/linux/ntsync.h | 2 ++
2 files changed, 33 insertions(+)
-diff --git a/drivers/misc/winesync.c b/drivers/misc/winesync.c
-index 98bedda2f8eb..eae272663abe 100644
---- a/drivers/misc/winesync.c
-+++ b/drivers/misc/winesync.c
-@@ -550,6 +550,35 @@ static int winesync_read_sem(struct winesync_device *dev, void __user *argp)
+diff --git a/drivers/misc/ntsync.c b/drivers/misc/ntsync.c
+index 70c60f294bb2..88adb52bad93 100644
+--- a/drivers/misc/ntsync.c
++++ b/drivers/misc/ntsync.c
+@@ -549,6 +549,35 @@ static int ntsync_read_sem(struct ntsync_device *dev, void __user *argp)
return 0;
}
-+static int winesync_read_mutex(struct winesync_device *dev, void __user *argp)
++static int ntsync_read_mutex(struct ntsync_device *dev, void __user *argp)
+{
-+ struct winesync_mutex_args __user *user_args = argp;
-+ struct winesync_mutex_args args;
-+ struct winesync_obj *mutex;
++ struct ntsync_mutex_args __user *user_args = argp;
++ struct ntsync_mutex_args args;
++ struct ntsync_obj *mutex;
+ __u32 id;
+ int ret;
+
+ if (get_user(id, &user_args->mutex))
+ return -EFAULT;
+
-+ mutex = get_obj_typed(dev, id, WINESYNC_TYPE_MUTEX);
++ mutex = get_obj_typed(dev, id, NTSYNC_TYPE_MUTEX);
+ if (!mutex)
+ return -EINVAL;
+
@@ -1777,447 +1792,754 @@ index 98bedda2f8eb..eae272663abe 100644
/*
* Actually change the mutex state to mark its owner as dead.
*/
-@@ -908,6 +937,8 @@ static long winesync_char_ioctl(struct file *file, unsigned int cmd,
- return winesync_put_mutex(dev, argp);
- case WINESYNC_IOC_PUT_SEM:
- return winesync_put_sem(dev, argp);
-+ case WINESYNC_IOC_READ_MUTEX:
-+ return winesync_read_mutex(dev, argp);
- case WINESYNC_IOC_READ_SEM:
- return winesync_read_sem(dev, argp);
- case WINESYNC_IOC_WAIT_ALL:
-diff --git a/include/uapi/linux/winesync.h b/include/uapi/linux/winesync.h
-index 311eb810647d..3371a303a927 100644
---- a/include/uapi/linux/winesync.h
-+++ b/include/uapi/linux/winesync.h
-@@ -49,5 +49,7 @@ struct winesync_wait_args {
- #define WINESYNC_IOC_KILL_OWNER _IOW (WINESYNC_IOC_BASE, 7, __u32)
- #define WINESYNC_IOC_READ_SEM _IOWR(WINESYNC_IOC_BASE, 8, \
- struct winesync_sem_args)
-+#define WINESYNC_IOC_READ_MUTEX _IOWR(WINESYNC_IOC_BASE, 9, \
-+ struct winesync_mutex_args)
+@@ -910,6 +939,8 @@ static long ntsync_char_ioctl(struct file *file, unsigned int cmd,
+ return ntsync_put_mutex(dev, argp);
+ case NTSYNC_IOC_PUT_SEM:
+ return ntsync_put_sem(dev, argp);
++ case NTSYNC_IOC_READ_MUTEX:
++ return ntsync_read_mutex(dev, argp);
+ case NTSYNC_IOC_READ_SEM:
+ return ntsync_read_sem(dev, argp);
+ case NTSYNC_IOC_WAIT_ALL:
+diff --git a/include/uapi/linux/ntsync.h b/include/uapi/linux/ntsync.h
+index b84a57c13d80..fa57f190c80e 100644
+--- a/include/uapi/linux/ntsync.h
++++ b/include/uapi/linux/ntsync.h
+@@ -51,5 +51,7 @@ struct ntsync_wait_args {
+ #define NTSYNC_IOC_KILL_OWNER _IOW (NTSYNC_IOC_BASE, 7, __u32)
+ #define NTSYNC_IOC_READ_SEM _IOWR(NTSYNC_IOC_BASE, 8, \
+ struct ntsync_sem_args)
++#define NTSYNC_IOC_READ_MUTEX _IOWR(NTSYNC_IOC_BASE, 9, \
++ struct ntsync_mutex_args)
#endif
--
-2.36.0
+2.43.0
-From e897f7ec5164d6d5d3d9881756be9a538c533487 Mon Sep 17 00:00:00 2001
-From: Zebediah Figura <zfigura@codeweavers.com>
-Date: Fri, 5 Mar 2021 11:50:49 -0600
-Subject: [PATCH 12/34] docs: winesync: Add documentation for the winesync
- uAPI.
+From 1bc3fa335b3c30797586eebbf533135ccddcb934 Mon Sep 17 00:00:00 2001
+From: Elizabeth Figura <zfigura@codeweavers.com>
+Date: Wed, 19 Jan 2022 18:21:03 -0600
+Subject: [PATCH 12/32] ntsync: Introduce NTSYNC_IOC_CREATE_EVENT.
+This corresponds to the NT syscall NtCreateEvent().
---
- Documentation/userspace-api/index.rst | 1 +
- Documentation/userspace-api/winesync.rst | 324 +++++++++++++++++++++++
- 2 files changed, 325 insertions(+)
- create mode 100644 Documentation/userspace-api/winesync.rst
+ drivers/misc/ntsync.c | 65 +++++++++++++++++++++++++++++++++++++
+ include/uapi/linux/ntsync.h | 8 +++++
+ 2 files changed, 73 insertions(+)
-diff --git a/Documentation/userspace-api/index.rst b/Documentation/userspace-api/index.rst
-index a61eac0c73f8..0bf697ddcb09 100644
---- a/Documentation/userspace-api/index.rst
-+++ b/Documentation/userspace-api/index.rst
-@@ -29,6 +29,7 @@ place where this information is gathered.
- sysfs-platform_profile
- vduse
- futex2
-+ winesync
+diff --git a/drivers/misc/ntsync.c b/drivers/misc/ntsync.c
+index 88adb52bad93..3778dbe617e9 100644
+--- a/drivers/misc/ntsync.c
++++ b/drivers/misc/ntsync.c
+@@ -17,6 +17,7 @@
+ enum ntsync_type {
+ NTSYNC_TYPE_SEM,
+ NTSYNC_TYPE_MUTEX,
++ NTSYNC_TYPE_EVENT,
+ };
- .. only:: subproject and html
+ struct ntsync_obj {
+@@ -66,6 +67,10 @@ struct ntsync_obj {
+ __u32 owner;
+ bool ownerdead;
+ } mutex;
++ struct {
++ bool manual;
++ bool signaled;
++ } event;
+ } u;
+ };
-diff --git a/Documentation/userspace-api/winesync.rst b/Documentation/userspace-api/winesync.rst
-new file mode 100644
-index 000000000000..34e54be229cf
---- /dev/null
-+++ b/Documentation/userspace-api/winesync.rst
-@@ -0,0 +1,324 @@
-+=====================================
-+Wine synchronization primitive driver
-+=====================================
-+
-+This page documents the user-space API for the winesync driver.
-+
-+winesync is a support driver for emulation of NT synchronization
-+primitives by the Wine project or other NT emulators. It exists
-+because implementation in user-space, using existing tools, cannot
-+simultaneously satisfy performance, correctness, and security
-+constraints. It is implemented entirely in software, and does not
-+drive any hardware device.
-+
-+This interface is meant as a compatibility tool only, and should not
-+be used for general synchronization. Instead use generic, versatile
-+interfaces such as futex(2) and poll(2).
-+
-+Synchronization primitives
-+==========================
-+
-+The winesync driver exposes two types of synchronization primitives,
-+semaphores and mutexes.
-+
-+A semaphore holds a single volatile 32-bit counter, and a static
-+32-bit integer denoting the maximum value. It is considered signaled
-+when the counter is nonzero. The counter is decremented by one when a
-+wait is satisfied. Both the initial and maximum count are established
-+when the semaphore is created.
-+
-+A mutex holds a volatile 32-bit recursion count, and a volatile 32-bit
-+identifier denoting its owner. A mutex is considered signaled when its
-+owner is zero (indicating that it is not owned). The recursion count
-+is incremented when a wait is satisfied, and ownership is set to the
-+given identifier.
-+
-+A mutex also holds an internal flag denoting whether its previous
-+owner has died; such a mutex is said to be inconsistent. Owner death
-+is not tracked automatically based on thread death, but rather must be
-+communicated using ``WINESYNC_IOC_KILL_OWNER``. An inconsistent mutex
-+is inherently considered unowned.
-+
-+Except for the "unowned" semantics of zero, the actual value of the
-+owner identifier is not interpreted by the winesync driver at all. The
-+intended use is to store a thread identifier; however, the winesync
-+driver does not actually validate that a calling thread provides
-+consistent or unique identifiers.
-+
-+Unless specified otherwise, all operations on an object are atomic and
-+totally ordered with respect to other operations on the same object.
-+
-+Objects are represented by unsigned 32-bit integers.
-+
-+Char device
-+===========
-+
-+The winesync driver creates a single char device /dev/winesync. Each
-+file description opened on the device represents a unique namespace.
-+That is, objects created on one open file description are shared
-+across all its individual descriptors, but are not shared with other
-+open() calls on the same device. The same file description may be
-+shared across multiple processes.
-+
-+ioctl reference
-+===============
-+
-+All operations on the device are done through ioctls. There are three
-+structures used in ioctl calls::
-+
-+ struct winesync_sem_args {
-+ __u32 sem;
-+ __u32 count;
-+ __u32 max;
-+ };
-+
-+ struct winesync_mutex_args {
-+ __u32 mutex;
-+ __u32 owner;
-+ __u32 count;
-+ };
-+
-+ struct winesync_wait_args {
-+ __u64 timeout;
-+ __u64 objs;
-+ __u32 count;
-+ __u32 owner;
-+ __u32 index;
-+ __u32 pad;
-+ };
-+
-+Depending on the ioctl, members of the structure may be used as input,
-+output, or not at all. All ioctls return 0 on success.
-+
-+The ioctls are as follows:
-+
-+.. c:macro:: WINESYNC_IOC_CREATE_SEM
-+
-+ Create a semaphore object. Takes a pointer to struct
-+ :c:type:`winesync_sem_args`, which is used as follows:
-+
-+ .. list-table::
-+
-+ * - ``sem``
-+ - On output, contains the identifier of the created semaphore.
-+ * - ``count``
-+ - Initial count of the semaphore.
-+ * - ``max``
-+ - Maximum count of the semaphore.
-+
-+ Fails with ``EINVAL`` if ``count`` is greater than ``max``.
-+
-+.. c:macro:: WINESYNC_IOC_CREATE_MUTEX
-+
-+ Create a mutex object. Takes a pointer to struct
-+ :c:type:`winesync_mutex_args`, which is used as follows:
+@@ -199,6 +204,8 @@ static bool is_signaled(struct ntsync_obj *obj, __u32 owner)
+ if (obj->u.mutex.owner && obj->u.mutex.owner != owner)
+ return false;
+ return obj->u.mutex.count < UINT_MAX;
++ case NTSYNC_TYPE_EVENT:
++ return obj->u.event.signaled;
+ }
+
+ WARN(1, "bad object type %#x\n", obj->type);
+@@ -248,6 +255,10 @@ static void try_wake_all(struct ntsync_device *dev, struct ntsync_q *q,
+ obj->u.mutex.count++;
+ obj->u.mutex.owner = q->owner;
+ break;
++ case NTSYNC_TYPE_EVENT:
++ if (!obj->u.event.manual)
++ obj->u.event.signaled = false;
++ break;
+ }
+ }
+ wake_up_process(q->task);
+@@ -314,6 +325,26 @@ static void try_wake_any_mutex(struct ntsync_obj *mutex)
+ }
+ }
+
++static void try_wake_any_event(struct ntsync_obj *event)
++{
++ struct ntsync_q_entry *entry;
+
-+ .. list-table::
++ lockdep_assert_held(&event->lock);
+
-+ * - ``mutex``
-+ - On output, contains the identifier of the created mutex.
-+ * - ``count``
-+ - Initial recursion count of the mutex.
-+ * - ``owner``
-+ - Initial owner of the mutex.
++ list_for_each_entry(entry, &event->any_waiters, node) {
++ struct ntsync_q *q = entry->q;
+
-+ If ``owner`` is nonzero and ``count`` is zero, or if ``owner`` is
-+ zero and ``count`` is nonzero, the function fails with ``EINVAL``.
++ if (!event->u.event.signaled)
++ break;
+
-+.. c:macro:: WINESYNC_IOC_DELETE
++ if (atomic_cmpxchg(&q->signaled, -1, entry->index) == -1) {
++ if (!event->u.event.manual)
++ event->u.event.signaled = false;
++ wake_up_process(q->task);
++ }
++ }
++}
+
-+ Delete an object of any type. Takes an input-only pointer to a
-+ 32-bit integer denoting the object to delete.
+ static int ntsync_create_sem(struct ntsync_device *dev, void __user *argp)
+ {
+ struct ntsync_sem_args __user *user_args = argp;
+@@ -378,6 +409,35 @@ static int ntsync_create_mutex(struct ntsync_device *dev, void __user *argp)
+ return put_user(id, &user_args->mutex);
+ }
+
++static int ntsync_create_event(struct ntsync_device *dev, void __user *argp)
++{
++ struct ntsync_event_args __user *user_args = argp;
++ struct ntsync_event_args args;
++ struct ntsync_obj *event;
++ __u32 id;
++ int ret;
+
-+ Wait ioctls currently in progress are not interrupted, and behave as
-+ if the object remains valid.
++ if (copy_from_user(&args, argp, sizeof(args)))
++ return -EFAULT;
+
-+.. c:macro:: WINESYNC_IOC_PUT_SEM
++ event = kzalloc(sizeof(*event), GFP_KERNEL);
++ if (!event)
++ return -ENOMEM;
+
-+ Post to a semaphore object. Takes a pointer to struct
-+ :c:type:`winesync_sem_args`, which is used as follows:
++ init_obj(event);
++ event->type = NTSYNC_TYPE_EVENT;
++ event->u.event.manual = args.manual;
++ event->u.event.signaled = args.signaled;
+
-+ .. list-table::
++ ret = xa_alloc(&dev->objects, &id, event, xa_limit_32b, GFP_KERNEL);
++ if (ret < 0) {
++ kfree(event);
++ return ret;
++ }
+
-+ * - ``sem``
-+ - Semaphore object to post to.
-+ * - ``count``
-+ - Count to add to the semaphore. On output, contains the
-+ previous count of the semaphore.
-+ * - ``max``
-+ - Not used.
++ return put_user(id, &user_args->event);
++}
+
-+ If adding ``count`` to the semaphore's current count would raise the
-+ latter past the semaphore's maximum count, the ioctl fails with
-+ ``EOVERFLOW`` and the semaphore is not affected. If raising the
-+ semaphore's count causes it to become signaled, eligible threads
-+ waiting on this semaphore will be woken and the semaphore's count
-+ decremented appropriately.
+ static int ntsync_delete(struct ntsync_device *dev, void __user *argp)
+ {
+ struct ntsync_obj *obj;
+@@ -762,6 +822,9 @@ static void try_wake_any_obj(struct ntsync_obj *obj)
+ case NTSYNC_TYPE_MUTEX:
+ try_wake_any_mutex(obj);
+ break;
++ case NTSYNC_TYPE_EVENT:
++ try_wake_any_event(obj);
++ break;
+ }
+ }
+
+@@ -927,6 +990,8 @@ static long ntsync_char_ioctl(struct file *file, unsigned int cmd,
+ void __user *argp = (void __user *)parm;
+
+ switch (cmd) {
++ case NTSYNC_IOC_CREATE_EVENT:
++ return ntsync_create_event(dev, argp);
+ case NTSYNC_IOC_CREATE_MUTEX:
+ return ntsync_create_mutex(dev, argp);
+ case NTSYNC_IOC_CREATE_SEM:
+diff --git a/include/uapi/linux/ntsync.h b/include/uapi/linux/ntsync.h
+index fa57f190c80e..c7cbdeff32c9 100644
+--- a/include/uapi/linux/ntsync.h
++++ b/include/uapi/linux/ntsync.h
+@@ -22,6 +22,12 @@ struct ntsync_mutex_args {
+ __u32 count;
+ };
+
++struct ntsync_event_args {
++ __u32 event;
++ __u32 manual;
++ __u32 signaled;
++};
+
-+.. c:macro:: WINESYNC_IOC_PUT_MUTEX
+ struct ntsync_wait_args {
+ __u64 timeout;
+ __u64 objs;
+@@ -53,5 +59,7 @@ struct ntsync_wait_args {
+ struct ntsync_sem_args)
+ #define NTSYNC_IOC_READ_MUTEX _IOWR(NTSYNC_IOC_BASE, 9, \
+ struct ntsync_mutex_args)
++#define NTSYNC_IOC_CREATE_EVENT _IOWR(NTSYNC_IOC_BASE, 10, \
++ struct ntsync_event_args)
+
+ #endif
+--
+2.43.0
+
+From d4d9e2196dc13cf89b8181eb4eee86d4a26ef026 Mon Sep 17 00:00:00 2001
+From: Elizabeth Figura <zfigura@codeweavers.com>
+Date: Wed, 19 Jan 2022 18:43:30 -0600
+Subject: [PATCH 13/32] ntsync: Introduce NTSYNC_IOC_SET_EVENT.
+
+This corresponds to the NT syscall NtSetEvent().
+---
+ drivers/misc/ntsync.c | 45 +++++++++++++++++++++++++++++++++++++
+ include/uapi/linux/ntsync.h | 2 ++
+ 2 files changed, 47 insertions(+)
+
+diff --git a/drivers/misc/ntsync.c b/drivers/misc/ntsync.c
+index 3778dbe617e9..cd6478bd93bd 100644
+--- a/drivers/misc/ntsync.c
++++ b/drivers/misc/ntsync.c
+@@ -703,6 +703,49 @@ static int ntsync_kill_owner(struct ntsync_device *dev, void __user *argp)
+ return 0;
+ }
+
++static int ntsync_set_event(struct ntsync_device *dev, void __user *argp)
++{
++ struct ntsync_event_args __user *user_args = argp;
++ struct ntsync_event_args args;
++ struct ntsync_obj *event;
++ bool prev_state;
+
-+ Release a mutex object. Takes a pointer to struct
-+ :c:type:`winesync_mutex_args`, which is used as follows:
++ if (copy_from_user(&args, argp, sizeof(args)))
++ return -EFAULT;
+
-+ .. list-table::
++ event = get_obj_typed(dev, args.event, NTSYNC_TYPE_EVENT);
++ if (!event)
++ return -EINVAL;
+
-+ * - ``mutex``
-+ - Mutex object to release.
-+ * - ``owner``
-+ - Mutex owner identifier.
-+ * - ``count``
-+ - On output, contains the previous recursion count.
++ if (atomic_read(&event->all_hint) > 0) {
++ spin_lock(&dev->wait_all_lock);
++ spin_lock_nest_lock(&event->lock, &dev->wait_all_lock);
+
-+ If ``owner`` is zero, the ioctl fails with ``EINVAL``. If ``owner``
-+ is not the current owner of the mutex, the ioctl fails with
-+ ``EPERM``.
++ prev_state = event->u.event.signaled;
++ event->u.event.signaled = true;
++ try_wake_all_obj(dev, event);
++ try_wake_any_event(event);
+
-+ The mutex's count will be decremented by one. If decrementing the
-+ mutex's count causes it to become zero, the mutex is marked as
-+ unowned and signaled, and eligible threads waiting on it will be
-+ woken as appropriate.
++ spin_unlock(&event->lock);
++ spin_unlock(&dev->wait_all_lock);
++ } else {
++ spin_lock(&event->lock);
+
-+.. c:macro:: WINESYNC_IOC_READ_SEM
++ prev_state = event->u.event.signaled;
++ event->u.event.signaled = true;
++ try_wake_any_event(event);
+
-+ Read the current state of a semaphore object. Takes a pointer to
-+ struct :c:type:`winesync_sem_args`, which is used as follows:
++ spin_unlock(&event->lock);
++ }
+
-+ .. list-table::
++ put_obj(event);
+
-+ * - ``sem``
-+ - Semaphore object to read.
-+ * - ``count``
-+ - On output, contains the current count of the semaphore.
-+ * - ``max``
-+ - On output, contains the maximum count of the semaphore.
++ if (put_user(prev_state, &user_args->signaled))
++ return -EFAULT;
+
-+.. c:macro:: WINESYNC_IOC_READ_MUTEX
++ return 0;
++}
+
-+ Read the current state of a mutex object. Takes a pointer to struct
-+ :c:type:`winesync_mutex_args`, which is used as follows:
+ static int ntsync_schedule(const struct ntsync_q *q, ktime_t *timeout)
+ {
+ int ret = 0;
+@@ -1008,6 +1051,8 @@ static long ntsync_char_ioctl(struct file *file, unsigned int cmd,
+ return ntsync_read_mutex(dev, argp);
+ case NTSYNC_IOC_READ_SEM:
+ return ntsync_read_sem(dev, argp);
++ case NTSYNC_IOC_SET_EVENT:
++ return ntsync_set_event(dev, argp);
+ case NTSYNC_IOC_WAIT_ALL:
+ return ntsync_wait_all(dev, argp);
+ case NTSYNC_IOC_WAIT_ANY:
+diff --git a/include/uapi/linux/ntsync.h b/include/uapi/linux/ntsync.h
+index c7cbdeff32c9..8a230f5d4b3f 100644
+--- a/include/uapi/linux/ntsync.h
++++ b/include/uapi/linux/ntsync.h
+@@ -61,5 +61,7 @@ struct ntsync_wait_args {
+ struct ntsync_mutex_args)
+ #define NTSYNC_IOC_CREATE_EVENT _IOWR(NTSYNC_IOC_BASE, 10, \
+ struct ntsync_event_args)
++#define NTSYNC_IOC_SET_EVENT _IOWR(NTSYNC_IOC_BASE, 11, \
++ struct ntsync_event_args)
+
+ #endif
+--
+2.43.0
+
+From 03224658123725d6b8a27b55cd103ad782ebad7b Mon Sep 17 00:00:00 2001
+From: Elizabeth Figura <zfigura@codeweavers.com>
+Date: Wed, 19 Jan 2022 19:00:25 -0600
+Subject: [PATCH 14/32] ntsync: Introduce NTSYNC_IOC_RESET_EVENT.
+
+This corresponds to the NT syscall NtResetEvent().
+---
+ drivers/misc/ntsync.c | 31 +++++++++++++++++++++++++++++++
+ include/uapi/linux/ntsync.h | 2 ++
+ 2 files changed, 33 insertions(+)
+
+diff --git a/drivers/misc/ntsync.c b/drivers/misc/ntsync.c
+index cd6478bd93bd..151714dee0ff 100644
+--- a/drivers/misc/ntsync.c
++++ b/drivers/misc/ntsync.c
+@@ -746,6 +746,35 @@ static int ntsync_set_event(struct ntsync_device *dev, void __user *argp)
+ return 0;
+ }
+
++static int ntsync_reset_event(struct ntsync_device *dev, void __user *argp)
++{
++ struct ntsync_event_args __user *user_args = argp;
++ struct ntsync_event_args args;
++ struct ntsync_obj *event;
++ bool prev_state;
+
-+ .. list-table::
++ if (copy_from_user(&args, argp, sizeof(args)))
++ return -EFAULT;
+
-+ * - ``mutex``
-+ - Mutex object to read.
-+ * - ``owner``
-+ - On output, contains the current owner of the mutex, or zero
-+ if the mutex is not currently owned.
-+ * - ``count``
-+ - On output, contains the current recursion count of the mutex.
++ event = get_obj_typed(dev, args.event, NTSYNC_TYPE_EVENT);
++ if (!event)
++ return -EINVAL;
+
-+ If the mutex is marked as inconsistent, the function fails with
-+ ``EOWNERDEAD``. In this case, ``count`` and ``owner`` are set to
-+ zero.
++ spin_lock(&event->lock);
+
-+.. c:macro:: WINESYNC_IOC_KILL_OWNER
++ prev_state = event->u.event.signaled;
++ event->u.event.signaled = false;
+
-+ Mark any mutexes owned by the given owner as unowned and
-+ inconsistent. Takes an input-only pointer to a 32-bit integer
-+ denoting the owner. If the owner is zero, the ioctl fails with
-+ ``EINVAL``.
++ spin_unlock(&event->lock);
+
-+ For each mutex currently owned by the given owner, eligible threads
-+ waiting on said mutex will be woken as appropriate (and such waits
-+ will fail with ``EOWNERDEAD``, as described below).
++ put_obj(event);
+
-+ The operation as a whole is not atomic; however, the modification of
-+ each mutex is atomic and totally ordered with respect to other
-+ operations on the same mutex.
++ if (put_user(prev_state, &user_args->signaled))
++ return -EFAULT;
+
-+.. c:macro:: WINESYNC_IOC_WAIT_ANY
++ return 0;
++}
+
-+ Poll on any of a list of objects, atomically acquiring at most one.
-+ Takes a pointer to struct :c:type:`winesync_wait_args`, which is
-+ used as follows:
+ static int ntsync_schedule(const struct ntsync_q *q, ktime_t *timeout)
+ {
+ int ret = 0;
+@@ -1051,6 +1080,8 @@ static long ntsync_char_ioctl(struct file *file, unsigned int cmd,
+ return ntsync_read_mutex(dev, argp);
+ case NTSYNC_IOC_READ_SEM:
+ return ntsync_read_sem(dev, argp);
++ case NTSYNC_IOC_RESET_EVENT:
++ return ntsync_reset_event(dev, argp);
+ case NTSYNC_IOC_SET_EVENT:
+ return ntsync_set_event(dev, argp);
+ case NTSYNC_IOC_WAIT_ALL:
+diff --git a/include/uapi/linux/ntsync.h b/include/uapi/linux/ntsync.h
+index 8a230f5d4b3f..806125856117 100644
+--- a/include/uapi/linux/ntsync.h
++++ b/include/uapi/linux/ntsync.h
+@@ -63,5 +63,7 @@ struct ntsync_wait_args {
+ struct ntsync_event_args)
+ #define NTSYNC_IOC_SET_EVENT _IOWR(NTSYNC_IOC_BASE, 11, \
+ struct ntsync_event_args)
++#define NTSYNC_IOC_RESET_EVENT _IOWR(NTSYNC_IOC_BASE, 12, \
++ struct ntsync_event_args)
+
+ #endif
+--
+2.43.0
+
+From 16daeb0c9b8d95ab27c0c807c49ddebb5dba52c0 Mon Sep 17 00:00:00 2001
+From: Elizabeth Figura <zfigura@codeweavers.com>
+Date: Wed, 19 Jan 2022 19:10:12 -0600
+Subject: [PATCH 15/32] ntsync: Introduce NTSYNC_IOC_PULSE_EVENT.
+
+This corresponds to the NT syscall NtPulseEvent().
+---
+ drivers/misc/ntsync.c | 11 +++++++++--
+ include/uapi/linux/ntsync.h | 2 ++
+ 2 files changed, 11 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/misc/ntsync.c b/drivers/misc/ntsync.c
+index 151714dee0ff..45405d01e11d 100644
+--- a/drivers/misc/ntsync.c
++++ b/drivers/misc/ntsync.c
+@@ -703,7 +703,8 @@ static int ntsync_kill_owner(struct ntsync_device *dev, void __user *argp)
+ return 0;
+ }
+
+-static int ntsync_set_event(struct ntsync_device *dev, void __user *argp)
++static int ntsync_set_event(struct ntsync_device *dev, void __user *argp,
++ bool pulse)
+ {
+ struct ntsync_event_args __user *user_args = argp;
+ struct ntsync_event_args args;
+@@ -725,6 +726,8 @@ static int ntsync_set_event(struct ntsync_device *dev, void __user *argp)
+ event->u.event.signaled = true;
+ try_wake_all_obj(dev, event);
+ try_wake_any_event(event);
++ if (pulse)
++ event->u.event.signaled = false;
+
+ spin_unlock(&event->lock);
+ spin_unlock(&dev->wait_all_lock);
+@@ -734,6 +737,8 @@ static int ntsync_set_event(struct ntsync_device *dev, void __user *argp)
+ prev_state = event->u.event.signaled;
+ event->u.event.signaled = true;
+ try_wake_any_event(event);
++ if (pulse)
++ event->u.event.signaled = false;
+
+ spin_unlock(&event->lock);
+ }
+@@ -1072,6 +1077,8 @@ static long ntsync_char_ioctl(struct file *file, unsigned int cmd,
+ return ntsync_delete(dev, argp);
+ case NTSYNC_IOC_KILL_OWNER:
+ return ntsync_kill_owner(dev, argp);
++ case NTSYNC_IOC_PULSE_EVENT:
++ return ntsync_set_event(dev, argp, true);
+ case NTSYNC_IOC_PUT_MUTEX:
+ return ntsync_put_mutex(dev, argp);
+ case NTSYNC_IOC_PUT_SEM:
+@@ -1083,7 +1090,7 @@ static long ntsync_char_ioctl(struct file *file, unsigned int cmd,
+ case NTSYNC_IOC_RESET_EVENT:
+ return ntsync_reset_event(dev, argp);
+ case NTSYNC_IOC_SET_EVENT:
+- return ntsync_set_event(dev, argp);
++ return ntsync_set_event(dev, argp, false);
+ case NTSYNC_IOC_WAIT_ALL:
+ return ntsync_wait_all(dev, argp);
+ case NTSYNC_IOC_WAIT_ANY:
+diff --git a/include/uapi/linux/ntsync.h b/include/uapi/linux/ntsync.h
+index 806125856117..30f56b4388c8 100644
+--- a/include/uapi/linux/ntsync.h
++++ b/include/uapi/linux/ntsync.h
+@@ -65,5 +65,7 @@ struct ntsync_wait_args {
+ struct ntsync_event_args)
+ #define NTSYNC_IOC_RESET_EVENT _IOWR(NTSYNC_IOC_BASE, 12, \
+ struct ntsync_event_args)
++#define NTSYNC_IOC_PULSE_EVENT _IOWR(NTSYNC_IOC_BASE, 13, \
++ struct ntsync_event_args)
+
+ #endif
+--
+2.43.0
+
+From c264fe3627e7032d88cd6d56f4ce6a2c2fbc30af Mon Sep 17 00:00:00 2001
+From: Elizabeth Figura <zfigura@codeweavers.com>
+Date: Wed, 19 Jan 2022 19:14:00 -0600
+Subject: [PATCH 16/32] ntsync: Introduce NTSYNC_IOC_READ_EVENT.
+
+This corresponds to the NT syscall NtQueryEvent().
+---
+ drivers/misc/ntsync.c | 29 +++++++++++++++++++++++++++++
+ include/uapi/linux/ntsync.h | 2 ++
+ 2 files changed, 31 insertions(+)
+
+diff --git a/drivers/misc/ntsync.c b/drivers/misc/ntsync.c
+index 45405d01e11d..6821d9aa967d 100644
+--- a/drivers/misc/ntsync.c
++++ b/drivers/misc/ntsync.c
+@@ -638,6 +638,33 @@ static int ntsync_read_mutex(struct ntsync_device *dev, void __user *argp)
+ return ret;
+ }
+
++static int ntsync_read_event(struct ntsync_device *dev, void __user *argp)
++{
++ struct ntsync_event_args __user *user_args = argp;
++ struct ntsync_event_args args;
++ struct ntsync_obj *event;
++ __u32 id;
+
-+ .. list-table::
++ if (get_user(id, &user_args->event))
++ return -EFAULT;
+
-+ * - ``timeout``
-+ - Optional pointer to a 64-bit struct :c:type:`timespec`
-+ (specified as an integer so that the structure has the same
-+ size regardless of architecture). The timeout is specified in
-+ absolute format, as measured against the MONOTONIC clock. If
-+ the timeout is equal to or earlier than the current time, the
-+ function returns immediately without sleeping. If ``timeout``
-+ is zero, i.e. NULL, the function will sleep until an object
-+ is signaled, and will not fail with ``ETIMEDOUT``.
-+ * - ``objs``
-+ - Pointer to an array of ``count`` 32-bit object identifiers
-+ (specified as an integer so that the structure has the same
-+ size regardless of architecture). If any identifier is
-+ invalid, the function fails with ``EINVAL``.
-+ * - ``count``
-+ - Number of object identifiers specified in the ``objs`` array.
-+ * - ``owner``
-+ - Mutex owner identifier. If any object in ``objs`` is a mutex,
-+ the ioctl will attempt to acquire that mutex on behalf of
-+ ``owner``. If ``owner`` is zero, the ioctl fails with
-+ ``EINVAL``.
-+ * - ``index``
-+ - On success, contains the index (into ``objs``) of the object
-+ which was signaled.
-+ * - ``pad``
-+ - This field is not used and must be set to zero.
++ event = get_obj_typed(dev, id, NTSYNC_TYPE_EVENT);
++ if (!event)
++ return -EINVAL;
+
-+ This function attempts to acquire one of the given objects. If
-+ unable to do so, it sleeps until an object becomes signaled,
-+ subsequently acquiring it, or the timeout expires. In the latter
-+ case the ioctl fails with ``ETIMEDOUT``. The function only acquires
-+ one object, even if multiple objects are signaled.
++ args.event = id;
++ spin_lock(&event->lock);
++ args.manual = event->u.event.manual;
++ args.signaled = event->u.event.signaled;
++ spin_unlock(&event->lock);
+
-+ A semaphore is considered to be signaled if its count is nonzero,
-+ and is acquired by decrementing its count by one. A mutex is
-+ considered to be signaled if it is unowned or if its owner matches
-+ the ``owner`` argument, and is acquired by incrementing its
-+ recursion count by one and setting its owner to the ``owner``
-+ argument.
++ put_obj(event);
+
-+ Acquisition is atomic and totally ordered with respect to other
-+ operations on the same object. If two wait operations (with
-+ different ``owner`` identifiers) are queued on the same mutex, only
-+ one is signaled. If two wait operations are queued on the same
-+ semaphore, and a value of one is posted to it, only one is signaled.
-+ The order in which threads are signaled is not specified.
++ if (copy_to_user(user_args, &args, sizeof(args)))
++ return -EFAULT;
++ return 0;
++}
+
-+ If an inconsistent mutex is acquired, the ioctl fails with
-+ ``EOWNERDEAD``. Although this is a failure return, the function may
-+ otherwise be considered successful. The mutex is marked as owned by
-+ the given owner (with a recursion count of 1) and as no longer
-+ inconsistent, and ``index`` is still set to the index of the mutex.
+ /*
+ * Actually change the mutex state to mark its owner as dead.
+ */
+@@ -1083,6 +1110,8 @@ static long ntsync_char_ioctl(struct file *file, unsigned int cmd,
+ return ntsync_put_mutex(dev, argp);
+ case NTSYNC_IOC_PUT_SEM:
+ return ntsync_put_sem(dev, argp);
++ case NTSYNC_IOC_READ_EVENT:
++ return ntsync_read_event(dev, argp);
+ case NTSYNC_IOC_READ_MUTEX:
+ return ntsync_read_mutex(dev, argp);
+ case NTSYNC_IOC_READ_SEM:
+diff --git a/include/uapi/linux/ntsync.h b/include/uapi/linux/ntsync.h
+index 30f56b4388c8..86c28b909777 100644
+--- a/include/uapi/linux/ntsync.h
++++ b/include/uapi/linux/ntsync.h
+@@ -67,5 +67,7 @@ struct ntsync_wait_args {
+ struct ntsync_event_args)
+ #define NTSYNC_IOC_PULSE_EVENT _IOWR(NTSYNC_IOC_BASE, 13, \
+ struct ntsync_event_args)
++#define NTSYNC_IOC_READ_EVENT _IOWR(NTSYNC_IOC_BASE, 14, \
++ struct ntsync_event_args)
+
+ #endif
+--
+2.43.0
+
+From 198ddbebdbe3d062505bde44619da050eead04e8 Mon Sep 17 00:00:00 2001
+From: Elizabeth Figura <zfigura@codeweavers.com>
+Date: Wed, 13 Apr 2022 20:02:39 -0500
+Subject: [PATCH 17/32] ntsync: Introduce alertable waits.
+
+This implements the "alertable" feature of NtWaitForMultipleObjects().
+Alerts are implemented using events; the user-space NT emulator is expected to
+create an internal ntsync event for each thread and pass that event to wait
+functions.
+---
+ drivers/misc/ntsync.c | 68 ++++++++++++++++++++++++++++++++-----
+ include/uapi/linux/ntsync.h | 2 +-
+ 2 files changed, 60 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/misc/ntsync.c b/drivers/misc/ntsync.c
+index 6821d9aa967d..6f4cb9a3ed5a 100644
+--- a/drivers/misc/ntsync.c
++++ b/drivers/misc/ntsync.c
+@@ -840,10 +840,11 @@ static int setup_wait(struct ntsync_device *dev,
+ const __u32 count = args->count;
+ struct ntsync_q *q;
+ ktime_t timeout = 0;
++ __u32 total_count;
+ __u32 *ids;
+ __u32 i, j;
+
+- if (!args->owner || args->pad)
++ if (!args->owner)
+ return -EINVAL;
+
+ if (args->count > NTSYNC_MAX_WAIT_COUNT)
+@@ -860,7 +861,11 @@ static int setup_wait(struct ntsync_device *dev,
+ timeout = timespec64_to_ns(&to);
+ }
+
+- ids = kmalloc_array(count, sizeof(*ids), GFP_KERNEL);
++ total_count = count;
++ if (args->alert)
++ total_count++;
+
-+ It is valid to pass the same object more than once. If a wakeup
-+ occurs due to that object being signaled, ``index`` is set to the
-+ lowest index corresponding to that object.
++ ids = kmalloc_array(total_count, sizeof(*ids), GFP_KERNEL);
+ if (!ids)
+ return -ENOMEM;
+ if (copy_from_user(ids, u64_to_user_ptr(args->objs),
+@@ -868,8 +873,10 @@ static int setup_wait(struct ntsync_device *dev,
+ kfree(ids);
+ return -EFAULT;
+ }
++ if (args->alert)
++ ids[count] = args->alert;
+
+- q = kmalloc(struct_size(q, entries, count), GFP_KERNEL);
++ q = kmalloc(struct_size(q, entries, total_count), GFP_KERNEL);
+ if (!q) {
+ kfree(ids);
+ return -ENOMEM;
+@@ -881,7 +888,7 @@ static int setup_wait(struct ntsync_device *dev,
+ q->ownerdead = false;
+ q->count = count;
+
+- for (i = 0; i < count; i++) {
++ for (i = 0; i < total_count; i++) {
+ struct ntsync_q_entry *entry = &q->entries[i];
+ struct ntsync_obj *obj = get_obj(dev, ids[i]);
+
+@@ -936,9 +943,9 @@ static int ntsync_wait_any(struct ntsync_device *dev, void __user *argp)
+ {
+ struct ntsync_wait_args args;
+ struct ntsync_q *q;
++ __u32 i, total_count;
+ ktime_t timeout;
+ int signaled;
+- __u32 i;
+ int ret;
+
+ if (copy_from_user(&args, argp, sizeof(args)))
+@@ -948,9 +955,13 @@ static int ntsync_wait_any(struct ntsync_device *dev, void __user *argp)
+ if (ret < 0)
+ return ret;
+
++ total_count = args.count;
++ if (args.alert)
++ total_count++;
+
-+ The function may fail with ``EINTR`` if a signal is received.
+ /* queue ourselves */
+
+- for (i = 0; i < args.count; i++) {
++ for (i = 0; i < total_count; i++) {
+ struct ntsync_q_entry *entry = &q->entries[i];
+ struct ntsync_obj *obj = entry->obj;
+
+@@ -959,9 +970,15 @@ static int ntsync_wait_any(struct ntsync_device *dev, void __user *argp)
+ spin_unlock(&obj->lock);
+ }
+
+- /* check if we are already signaled */
++ /*
++ * Check if we are already signaled.
++ *
++ * Note that the API requires that normal objects are checked before
++ * the alert event. Hence we queue the alert event last, and check
++ * objects in order.
++ */
+
+- for (i = 0; i < args.count; i++) {
++ for (i = 0; i < total_count; i++) {
+ struct ntsync_obj *obj = q->entries[i].obj;
+
+ if (atomic_read(&q->signaled) != -1)
+@@ -978,7 +995,7 @@ static int ntsync_wait_any(struct ntsync_device *dev, void __user *argp)
+
+ /* and finally, unqueue */
+
+- for (i = 0; i < args.count; i++) {
++ for (i = 0; i < total_count; i++) {
+ struct ntsync_q_entry *entry = &q->entries[i];
+ struct ntsync_obj *obj = entry->obj;
+
+@@ -1038,6 +1055,14 @@ static int ntsync_wait_all(struct ntsync_device *dev, void __user *argp)
+ */
+ list_add_tail(&entry->node, &obj->all_waiters);
+ }
++ if (args.alert) {
++ struct ntsync_q_entry *entry = &q->entries[args.count];
++ struct ntsync_obj *obj = entry->obj;
+
-+.. c:macro:: WINESYNC_IOC_WAIT_ALL
++ spin_lock_nest_lock(&obj->lock, &dev->wait_all_lock);
++ list_add_tail(&entry->node, &obj->any_waiters);
++ spin_unlock(&obj->lock);
++ }
+
+ /* check if we are already signaled */
+
+@@ -1045,6 +1070,21 @@ static int ntsync_wait_all(struct ntsync_device *dev, void __user *argp)
+
+ spin_unlock(&dev->wait_all_lock);
+
++ /*
++ * Check if the alert event is signaled, making sure to do so only
++ * after checking if the other objects are signaled.
++ */
+
-+ Poll on a list of objects, atomically acquiring all of them. Takes a
-+ pointer to struct :c:type:`winesync_wait_args`, which is used
-+ identically to ``WINESYNC_IOC_WAIT_ANY``, except that ``index`` is
-+ always filled with zero on success.
++ if (args.alert) {
++ struct ntsync_obj *obj = q->entries[args.count].obj;
+
-+ This function attempts to simultaneously acquire all of the given
-+ objects. If unable to do so, it sleeps until all objects become
-+ simultaneously signaled, subsequently acquiring them, or the timeout
-+ expires. In the latter case the ioctl fails with ``ETIMEDOUT`` and
-+ no objects are modified.
++ if (atomic_read(&q->signaled) == -1) {
++ spin_lock(&obj->lock);
++ try_wake_any_obj(obj);
++ spin_unlock(&obj->lock);
++ }
++ }
+
-+ Objects may become signaled and subsequently designaled (through
-+ acquisition by other threads) while this thread is sleeping. Only
-+ once all objects are simultaneously signaled does the ioctl acquire
-+ them and return. The entire acquisition is atomic and totally
-+ ordered with respect to other operations on any of the given
-+ objects.
+ /* sleep */
+
+ ret = ntsync_schedule(q, args.timeout ? &timeout : NULL);
+@@ -1067,6 +1107,16 @@ static int ntsync_wait_all(struct ntsync_device *dev, void __user *argp)
+
+ put_obj(obj);
+ }
++ if (args.alert) {
++ struct ntsync_q_entry *entry = &q->entries[args.count];
++ struct ntsync_obj *obj = entry->obj;
+
-+ If an inconsistent mutex is acquired, the ioctl fails with
-+ ``EOWNERDEAD``. Similarly to ``WINESYNC_IOC_WAIT_ANY``, all objects
-+ are nevertheless marked as acquired. Note that if multiple mutex
-+ objects are specified, there is no way to know which were marked as
-+ inconsistent.
++ spin_lock_nest_lock(&obj->lock, &dev->wait_all_lock);
++ list_del(&entry->node);
++ spin_unlock(&obj->lock);
+
-+ Unlike ``WINESYNC_IOC_WAIT_ANY``, it is not valid to pass the same
-+ object more than once. If this is attempted, the function fails with
-+ ``EINVAL``.
++ put_obj(obj);
++ }
+
+ spin_unlock(&dev->wait_all_lock);
+
+diff --git a/include/uapi/linux/ntsync.h b/include/uapi/linux/ntsync.h
+index 86c28b909777..e145b36a15ea 100644
+--- a/include/uapi/linux/ntsync.h
++++ b/include/uapi/linux/ntsync.h
+@@ -34,7 +34,7 @@ struct ntsync_wait_args {
+ __u32 count;
+ __u32 owner;
+ __u32 index;
+- __u32 pad;
++ __u32 alert;
+ };
+
+ #define NTSYNC_MAX_WAIT_COUNT 64
--
-2.36.0
+2.43.0
-From 622699b7dd8d5390dccdd9be1159e93dee6815ac Mon Sep 17 00:00:00 2001
-From: Zebediah Figura <zfigura@codeweavers.com>
+From 9208836580ed5e5aadfdfaf59dc8352ff6c4a07c Mon Sep 17 00:00:00 2001
+From: Elizabeth Figura <zfigura@codeweavers.com>
Date: Fri, 5 Mar 2021 12:06:23 -0600
-Subject: [PATCH 13/34] selftests: winesync: Add some tests for semaphore
- state.
+Subject: [PATCH 18/32] selftests: ntsync: Add some tests for semaphore state.
---
tools/testing/selftests/Makefile | 1 +
- .../selftests/drivers/winesync/Makefile | 8 +
- .../testing/selftests/drivers/winesync/config | 1 +
- .../selftests/drivers/winesync/winesync.c | 153 ++++++++++++++++++
+ .../testing/selftests/drivers/ntsync/Makefile | 8 +
+ tools/testing/selftests/drivers/ntsync/config | 1 +
+ .../testing/selftests/drivers/ntsync/ntsync.c | 153 ++++++++++++++++++
4 files changed, 163 insertions(+)
- create mode 100644 tools/testing/selftests/drivers/winesync/Makefile
- create mode 100644 tools/testing/selftests/drivers/winesync/config
- create mode 100644 tools/testing/selftests/drivers/winesync/winesync.c
+ create mode 100644 tools/testing/selftests/drivers/ntsync/Makefile
+ create mode 100644 tools/testing/selftests/drivers/ntsync/config
+ create mode 100644 tools/testing/selftests/drivers/ntsync/ntsync.c
diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile
-index 8247a7c69..553c949dc 100644
+index 8247a7c69c36..40b7318a8e22 100644
--- a/tools/testing/selftests/Makefile
+++ b/tools/testing/selftests/Makefile
-@@ -18,6 +18,7 @@ TARGETS += drivers/dma-buf
+@@ -15,6 +15,7 @@ TARGETS += cpu-hotplug
+ TARGETS += damon
+ TARGETS += dmabuf-heaps
+ TARGETS += drivers/dma-buf
++TARGETS += drivers/ntsync
TARGETS += drivers/s390x/uvdevice
TARGETS += drivers/net/bonding
TARGETS += drivers/net/team
-+TARGETS += drivers/winesync
- TARGETS += dt
- TARGETS += efivarfs
- TARGETS += exec
-diff --git a/tools/testing/selftests/drivers/winesync/Makefile b/tools/testing/selftests/drivers/winesync/Makefile
+diff --git a/tools/testing/selftests/drivers/ntsync/Makefile b/tools/testing/selftests/drivers/ntsync/Makefile
new file mode 100644
-index 000000000000..43b39fdeea10
+index 000000000000..a34da5ccacf0
--- /dev/null
-+++ b/tools/testing/selftests/drivers/winesync/Makefile
++++ b/tools/testing/selftests/drivers/ntsync/Makefile
@@ -0,0 +1,8 @@
+# SPDX-LICENSE-IDENTIFIER: GPL-2.0-only
-+TEST_GEN_PROGS := winesync
++TEST_GEN_PROGS := ntsync
+
+top_srcdir =../../../../..
+CFLAGS += -I$(top_srcdir)/usr/include
+LDLIBS += -lpthread
+
+include ../../lib.mk
-diff --git a/tools/testing/selftests/drivers/winesync/config b/tools/testing/selftests/drivers/winesync/config
+diff --git a/tools/testing/selftests/drivers/ntsync/config b/tools/testing/selftests/drivers/ntsync/config
new file mode 100644
index 000000000000..60539c826d06
--- /dev/null
-+++ b/tools/testing/selftests/drivers/winesync/config
++++ b/tools/testing/selftests/drivers/ntsync/config
@@ -0,0 +1 @@
+CONFIG_WINESYNC=y
-diff --git a/tools/testing/selftests/drivers/winesync/winesync.c b/tools/testing/selftests/drivers/winesync/winesync.c
+diff --git a/tools/testing/selftests/drivers/ntsync/ntsync.c b/tools/testing/selftests/drivers/ntsync/ntsync.c
new file mode 100644
-index 000000000000..58ade297fef9
+index 000000000000..777c408e8f9e
--- /dev/null
-+++ b/tools/testing/selftests/drivers/winesync/winesync.c
++++ b/tools/testing/selftests/drivers/ntsync/ntsync.c
@@ -0,0 +1,153 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
-+ * Various unit tests for the "winesync" synchronization primitive driver.
++ * Various unit tests for the "ntsync" synchronization primitive driver.
+ *
-+ * Copyright (C) 2021 Zebediah Figura
++ * Copyright (C) 2021-2022 Elizabeth Figura
+ */
+
+#define _GNU_SOURCE
@@ -2226,18 +2548,18 @@ index 000000000000..58ade297fef9
+#include <fcntl.h>
+#include <time.h>
+#include <pthread.h>
-+#include <linux/winesync.h>
++#include <linux/ntsync.h>
+#include "../../kselftest_harness.h"
+
+static int read_sem_state(int fd, __u32 sem, __u32 *count, __u32 *max)
+{
-+ struct winesync_sem_args args;
++ struct ntsync_sem_args args;
+ int ret;
+
+ args.sem = sem;
+ args.count = 0xdeadbeef;
+ args.max = 0xdeadbeef;
-+ ret = ioctl(fd, WINESYNC_IOC_READ_SEM, &args);
++ ret = ioctl(fd, NTSYNC_IOC_READ_SEM, &args);
+ *count = args.count;
+ *max = args.max;
+ return ret;
@@ -2254,12 +2576,12 @@ index 000000000000..58ade297fef9
+
+static int put_sem(int fd, __u32 sem, __u32 *count)
+{
-+ struct winesync_sem_args args;
++ struct ntsync_sem_args args;
+ int ret;
+
+ args.sem = sem;
+ args.count = *count;
-+ ret = ioctl(fd, WINESYNC_IOC_PUT_SEM, &args);
++ ret = ioctl(fd, NTSYNC_IOC_PUT_SEM, &args);
+ *count = args.count;
+ return ret;
+}
@@ -2267,7 +2589,7 @@ index 000000000000..58ade297fef9
+static int wait_any(int fd, __u32 count, const __u32 *objs, __u32 owner,
+ __u32 *index)
+{
-+ struct winesync_wait_args args = {0};
++ struct ntsync_wait_args args = {0};
+ struct timespec timeout;
+ int ret;
+
@@ -2278,88 +2600,88 @@ index 000000000000..58ade297fef9
+ args.objs = (uintptr_t)objs;
+ args.owner = owner;
+ args.index = 0xdeadbeef;
-+ ret = ioctl(fd, WINESYNC_IOC_WAIT_ANY, &args);
++ ret = ioctl(fd, NTSYNC_IOC_WAIT_ANY, &args);
+ *index = args.index;
+ return ret;
+}
+
+TEST(semaphore_state)
+{
-+ struct winesync_sem_args sem_args;
++ struct ntsync_sem_args sem_args;
+ struct timespec timeout;
-+ __u32 sem, count, index;
++ __u32 count, index;
+ int fd, ret;
+
+ clock_gettime(CLOCK_MONOTONIC, &timeout);
+
-+ fd = open("/dev/winesync", O_CLOEXEC | O_RDONLY);
++ fd = open("/dev/ntsync", O_CLOEXEC | O_RDONLY);
+ ASSERT_LE(0, fd);
+
+ sem_args.count = 3;
+ sem_args.max = 2;
+ sem_args.sem = 0xdeadbeef;
-+ ret = ioctl(fd, WINESYNC_IOC_CREATE_SEM, &sem_args);
++ ret = ioctl(fd, NTSYNC_IOC_CREATE_SEM, &sem_args);
+ EXPECT_EQ(-1, ret);
+ EXPECT_EQ(EINVAL, errno);
+
+ sem_args.count = 2;
+ sem_args.max = 2;
+ sem_args.sem = 0xdeadbeef;
-+ ret = ioctl(fd, WINESYNC_IOC_CREATE_SEM, &sem_args);
++ ret = ioctl(fd, NTSYNC_IOC_CREATE_SEM, &sem_args);
+ EXPECT_EQ(0, ret);
+ EXPECT_NE(0xdeadbeef, sem_args.sem);
-+ check_sem_state(fd, sem, 2, 2);
++ check_sem_state(fd, sem_args.sem, 2, 2);
+
+ count = 0;
-+ ret = put_sem(fd, sem, &count);
++ ret = put_sem(fd, sem_args.sem, &count);
+ EXPECT_EQ(0, ret);
+ EXPECT_EQ(2, count);
-+ check_sem_state(fd, sem, 2, 2);
++ check_sem_state(fd, sem_args.sem, 2, 2);
+
+ count = 1;
-+ ret = put_sem(fd, sem, &count);
++ ret = put_sem(fd, sem_args.sem, &count);
+ EXPECT_EQ(-1, ret);
+ EXPECT_EQ(EOVERFLOW, errno);
-+ check_sem_state(fd, sem, 2, 2);
++ check_sem_state(fd, sem_args.sem, 2, 2);
+
-+ ret = wait_any(fd, 1, &sem, 123, &index);
++ ret = wait_any(fd, 1, &sem_args.sem, 123, &index);
+ EXPECT_EQ(0, ret);
+ EXPECT_EQ(0, index);
-+ check_sem_state(fd, sem, 1, 2);
++ check_sem_state(fd, sem_args.sem, 1, 2);
+
-+ ret = wait_any(fd, 1, &sem, 123, &index);
++ ret = wait_any(fd, 1, &sem_args.sem, 123, &index);
+ EXPECT_EQ(0, ret);
+ EXPECT_EQ(0, index);
-+ check_sem_state(fd, sem, 0, 2);
++ check_sem_state(fd, sem_args.sem, 0, 2);
+
-+ ret = wait_any(fd, 1, &sem, 123, &index);
++ ret = wait_any(fd, 1, &sem_args.sem, 123, &index);
+ EXPECT_EQ(-1, ret);
+ EXPECT_EQ(ETIMEDOUT, errno);
+
+ count = 3;
-+ ret = put_sem(fd, sem, &count);
++ ret = put_sem(fd, sem_args.sem, &count);
+ EXPECT_EQ(-1, ret);
+ EXPECT_EQ(EOVERFLOW, errno);
-+ check_sem_state(fd, sem, 0, 2);
++ check_sem_state(fd, sem_args.sem, 0, 2);
+
+ count = 2;
-+ ret = put_sem(fd, sem, &count);
++ ret = put_sem(fd, sem_args.sem, &count);
+ EXPECT_EQ(0, ret);
+ EXPECT_EQ(0, count);
-+ check_sem_state(fd, sem, 2, 2);
++ check_sem_state(fd, sem_args.sem, 2, 2);
+
-+ ret = wait_any(fd, 1, &sem, 123, &index);
++ ret = wait_any(fd, 1, &sem_args.sem, 123, &index);
+ EXPECT_EQ(0, ret);
-+ ret = wait_any(fd, 1, &sem, 123, &index);
++ ret = wait_any(fd, 1, &sem_args.sem, 123, &index);
+ EXPECT_EQ(0, ret);
+
+ count = 1;
-+ ret = put_sem(fd, sem, &count);
++ ret = put_sem(fd, sem_args.sem, &count);
+ EXPECT_EQ(0, ret);
+ EXPECT_EQ(0, count);
-+ check_sem_state(fd, sem, 1, 2);
++ check_sem_state(fd, sem_args.sem, 1, 2);
+
-+ ret = ioctl(fd, WINESYNC_IOC_DELETE, &sem);
++ ret = ioctl(fd, NTSYNC_IOC_DELETE, &sem_args.sem);
+ EXPECT_EQ(0, ret);
+
+ close(fd);
@@ -2367,34 +2689,34 @@ index 000000000000..58ade297fef9
+
+TEST_HARNESS_MAIN
--
-2.36.0
+2.43.0
-From c62acefda29b36849abde8134bf2a3fe8d893520 Mon Sep 17 00:00:00 2001
-From: Zebediah Figura <zfigura@codeweavers.com>
+From 7f8e2b5dedf3fe0192bcf7924d651d33df8898a9 Mon Sep 17 00:00:00 2001
+From: Elizabeth Figura <zfigura@codeweavers.com>
Date: Fri, 5 Mar 2021 12:07:04 -0600
-Subject: [PATCH 14/34] selftests: winesync: Add some tests for mutex state.
+Subject: [PATCH 19/32] selftests: ntsync: Add some tests for mutex state.
---
- .../selftests/drivers/winesync/winesync.c | 188 ++++++++++++++++++
+ .../testing/selftests/drivers/ntsync/ntsync.c | 188 ++++++++++++++++++
1 file changed, 188 insertions(+)
-diff --git a/tools/testing/selftests/drivers/winesync/winesync.c b/tools/testing/selftests/drivers/winesync/winesync.c
-index 58ade297fef9..801b776da5aa 100644
---- a/tools/testing/selftests/drivers/winesync/winesync.c
-+++ b/tools/testing/selftests/drivers/winesync/winesync.c
+diff --git a/tools/testing/selftests/drivers/ntsync/ntsync.c b/tools/testing/selftests/drivers/ntsync/ntsync.c
+index 777c408e8f9e..8390dbbb1dd5 100644
+--- a/tools/testing/selftests/drivers/ntsync/ntsync.c
++++ b/tools/testing/selftests/drivers/ntsync/ntsync.c
@@ -49,6 +49,42 @@ static int put_sem(int fd, __u32 sem, __u32 *count)
return ret;
}
+static int read_mutex_state(int fd, __u32 mutex, __u32 *count, __u32 *owner)
+{
-+ struct winesync_mutex_args args;
++ struct ntsync_mutex_args args;
+ int ret;
+
+ args.mutex = mutex;
+ args.count = 0xdeadbeef;
+ args.owner = 0xdeadbeef;
-+ ret = ioctl(fd, WINESYNC_IOC_READ_MUTEX, &args);
++ ret = ioctl(fd, NTSYNC_IOC_READ_MUTEX, &args);
+ *count = args.count;
+ *owner = args.owner;
+ return ret;
@@ -2411,13 +2733,13 @@ index 58ade297fef9..801b776da5aa 100644
+
+static int put_mutex(int fd, __u32 mutex, __u32 owner, __u32 *count)
+{
-+ struct winesync_mutex_args args;
++ struct ntsync_mutex_args args;
+ int ret;
+
+ args.mutex = mutex;
+ args.owner = owner;
+ args.count = 0xdeadbeef;
-+ ret = ioctl(fd, WINESYNC_IOC_PUT_MUTEX, &args);
++ ret = ioctl(fd, NTSYNC_IOC_PUT_MUTEX, &args);
+ *count = args.count;
+ return ret;
+}
@@ -2431,32 +2753,32 @@ index 58ade297fef9..801b776da5aa 100644
+TEST(mutex_state)
+{
-+ struct winesync_mutex_args mutex_args;
++ struct ntsync_mutex_args mutex_args;
+ __u32 mutex, owner, count, index;
+ struct timespec timeout;
+ int fd, ret;
+
+ clock_gettime(CLOCK_MONOTONIC, &timeout);
+
-+ fd = open("/dev/winesync", O_CLOEXEC | O_RDONLY);
++ fd = open("/dev/ntsync", O_CLOEXEC | O_RDONLY);
+ ASSERT_LE(0, fd);
+
+ mutex_args.owner = 123;
+ mutex_args.count = 0;
-+ ret = ioctl(fd, WINESYNC_IOC_CREATE_MUTEX, &mutex_args);
++ ret = ioctl(fd, NTSYNC_IOC_CREATE_MUTEX, &mutex_args);
+ EXPECT_EQ(-1, ret);
+ EXPECT_EQ(EINVAL, errno);
+
+ mutex_args.owner = 0;
+ mutex_args.count = 2;
-+ ret = ioctl(fd, WINESYNC_IOC_CREATE_MUTEX, &mutex_args);
++ ret = ioctl(fd, NTSYNC_IOC_CREATE_MUTEX, &mutex_args);
+ EXPECT_EQ(-1, ret);
+ EXPECT_EQ(EINVAL, errno);
+
+ mutex_args.owner = 123;
+ mutex_args.count = 2;
+ mutex_args.mutex = 0xdeadbeef;
-+ ret = ioctl(fd, WINESYNC_IOC_CREATE_MUTEX, &mutex_args);
++ ret = ioctl(fd, NTSYNC_IOC_CREATE_MUTEX, &mutex_args);
+ EXPECT_EQ(0, ret);
+ EXPECT_NE(0xdeadbeef, mutex_args.mutex);
+ mutex = mutex_args.mutex;
@@ -2505,22 +2827,22 @@ index 58ade297fef9..801b776da5aa 100644
+ EXPECT_EQ(ETIMEDOUT, errno);
+
+ owner = 0;
-+ ret = ioctl(fd, WINESYNC_IOC_KILL_OWNER, &owner);
++ ret = ioctl(fd, NTSYNC_IOC_KILL_OWNER, &owner);
+ EXPECT_EQ(-1, ret);
+ EXPECT_EQ(EINVAL, errno);
+
+ owner = 123;
-+ ret = ioctl(fd, WINESYNC_IOC_KILL_OWNER, &owner);
++ ret = ioctl(fd, NTSYNC_IOC_KILL_OWNER, &owner);
+ EXPECT_EQ(0, ret);
+ check_mutex_state(fd, mutex, 1, 456);
+
+ owner = 456;
-+ ret = ioctl(fd, WINESYNC_IOC_KILL_OWNER, &owner);
++ ret = ioctl(fd, NTSYNC_IOC_KILL_OWNER, &owner);
+ EXPECT_EQ(0, ret);
+
+ mutex_args.count = 0xdeadbeef;
+ mutex_args.owner = 0xdeadbeef;
-+ ret = ioctl(fd, WINESYNC_IOC_READ_MUTEX, &mutex_args);
++ ret = ioctl(fd, NTSYNC_IOC_READ_MUTEX, &mutex_args);
+ EXPECT_EQ(-1, ret);
+ EXPECT_EQ(EOWNERDEAD, errno);
+ EXPECT_EQ(0, mutex_args.count);
@@ -2528,7 +2850,7 @@ index 58ade297fef9..801b776da5aa 100644
+
+ mutex_args.count = 0xdeadbeef;
+ mutex_args.owner = 0xdeadbeef;
-+ ret = ioctl(fd, WINESYNC_IOC_READ_MUTEX, &mutex_args);
++ ret = ioctl(fd, NTSYNC_IOC_READ_MUTEX, &mutex_args);
+ EXPECT_EQ(-1, ret);
+ EXPECT_EQ(EOWNERDEAD, errno);
+ EXPECT_EQ(0, mutex_args.count);
@@ -2541,12 +2863,12 @@ index 58ade297fef9..801b776da5aa 100644
+ check_mutex_state(fd, mutex, 1, 123);
+
+ owner = 123;
-+ ret = ioctl(fd, WINESYNC_IOC_KILL_OWNER, &owner);
++ ret = ioctl(fd, NTSYNC_IOC_KILL_OWNER, &owner);
+ EXPECT_EQ(0, ret);
+
+ mutex_args.count = 0xdeadbeef;
+ mutex_args.owner = 0xdeadbeef;
-+ ret = ioctl(fd, WINESYNC_IOC_READ_MUTEX, &mutex_args);
++ ret = ioctl(fd, NTSYNC_IOC_READ_MUTEX, &mutex_args);
+ EXPECT_EQ(-1, ret);
+ EXPECT_EQ(EOWNERDEAD, errno);
+ EXPECT_EQ(0, mutex_args.count);
@@ -2558,13 +2880,13 @@ index 58ade297fef9..801b776da5aa 100644
+ EXPECT_EQ(0, index);
+ check_mutex_state(fd, mutex, 1, 123);
+
-+ ret = ioctl(fd, WINESYNC_IOC_DELETE, &mutex);
++ ret = ioctl(fd, NTSYNC_IOC_DELETE, &mutex);
+ EXPECT_EQ(0, ret);
+
+ mutex_args.owner = 0;
+ mutex_args.count = 0;
+ mutex_args.mutex = 0xdeadbeef;
-+ ret = ioctl(fd, WINESYNC_IOC_CREATE_MUTEX, &mutex_args);
++ ret = ioctl(fd, NTSYNC_IOC_CREATE_MUTEX, &mutex_args);
+ EXPECT_EQ(0, ret);
+ EXPECT_NE(0xdeadbeef, mutex_args.mutex);
+ mutex = mutex_args.mutex;
@@ -2575,7 +2897,7 @@ index 58ade297fef9..801b776da5aa 100644
+ EXPECT_EQ(0, index);
+ check_mutex_state(fd, mutex, 1, 123);
+
-+ ret = ioctl(fd, WINESYNC_IOC_DELETE, &mutex_args.mutex);
++ ret = ioctl(fd, NTSYNC_IOC_DELETE, &mutex_args.mutex);
+ EXPECT_EQ(0, ret);
+
+ close(fd);
@@ -2583,51 +2905,51 @@ index 58ade297fef9..801b776da5aa 100644
+
TEST_HARNESS_MAIN
--
-2.36.0
+2.43.0
-From 540cefcfe255d0b4c7208ae57a43fe0f16ce2531 Mon Sep 17 00:00:00 2001
-From: Zebediah Figura <zfigura@codeweavers.com>
+From 596798d186edb9ca00396222e9dc0c43fcb40548 Mon Sep 17 00:00:00 2001
+From: Elizabeth Figura <zfigura@codeweavers.com>
Date: Fri, 5 Mar 2021 12:07:45 -0600
-Subject: [PATCH 15/34] selftests: winesync: Add some tests for
+Subject: [PATCH 20/32] selftests: ntsync: Add some tests for
WINESYNC_IOC_WAIT_ANY.
---
- .../selftests/drivers/winesync/winesync.c | 107 ++++++++++++++++++
+ .../testing/selftests/drivers/ntsync/ntsync.c | 107 ++++++++++++++++++
1 file changed, 107 insertions(+)
-diff --git a/tools/testing/selftests/drivers/winesync/winesync.c b/tools/testing/selftests/drivers/winesync/winesync.c
-index 801b776da5aa..5903061d38b6 100644
---- a/tools/testing/selftests/drivers/winesync/winesync.c
-+++ b/tools/testing/selftests/drivers/winesync/winesync.c
+diff --git a/tools/testing/selftests/drivers/ntsync/ntsync.c b/tools/testing/selftests/drivers/ntsync/ntsync.c
+index 8390dbbb1dd5..8ae930e7a601 100644
+--- a/tools/testing/selftests/drivers/ntsync/ntsync.c
++++ b/tools/testing/selftests/drivers/ntsync/ntsync.c
@@ -338,4 +338,111 @@ TEST(mutex_state)
close(fd);
}
+TEST(test_wait_any)
+{
-+ struct winesync_mutex_args mutex_args = {0};
-+ struct winesync_wait_args wait_args = {0};
-+ struct winesync_sem_args sem_args = {0};
++ struct ntsync_mutex_args mutex_args = {0};
++ struct ntsync_wait_args wait_args = {0};
++ struct ntsync_sem_args sem_args = {0};
+ __u32 objs[2], owner, index;
+ struct timespec timeout;
+ int fd, ret;
+
+ clock_gettime(CLOCK_MONOTONIC, &timeout);
+
-+ fd = open("/dev/winesync", O_CLOEXEC | O_RDONLY);
++ fd = open("/dev/ntsync", O_CLOEXEC | O_RDONLY);
+ ASSERT_LE(0, fd);
+
+ sem_args.count = 2;
+ sem_args.max = 3;
+ sem_args.sem = 0xdeadbeef;
-+ ret = ioctl(fd, WINESYNC_IOC_CREATE_SEM, &sem_args);
++ ret = ioctl(fd, NTSYNC_IOC_CREATE_SEM, &sem_args);
+ EXPECT_EQ(0, ret);
+ EXPECT_NE(0xdeadbeef, sem_args.sem);
+
+ mutex_args.owner = 0;
+ mutex_args.count = 0;
+ mutex_args.mutex = 0xdeadbeef;
-+ ret = ioctl(fd, WINESYNC_IOC_CREATE_MUTEX, &mutex_args);
++ ret = ioctl(fd, NTSYNC_IOC_CREATE_MUTEX, &mutex_args);
+ EXPECT_EQ(0, ret);
+ EXPECT_NE(0xdeadbeef, mutex_args.mutex);
+
@@ -2653,7 +2975,7 @@ index 801b776da5aa..5903061d38b6 100644
+ check_mutex_state(fd, mutex_args.mutex, 1, 123);
+
+ sem_args.count = 1;
-+ ret = ioctl(fd, WINESYNC_IOC_PUT_SEM, &sem_args);
++ ret = ioctl(fd, NTSYNC_IOC_PUT_SEM, &sem_args);
+ EXPECT_EQ(0, ret);
+ EXPECT_EQ(0, sem_args.count);
+
@@ -2674,7 +2996,7 @@ index 801b776da5aa..5903061d38b6 100644
+ EXPECT_EQ(ETIMEDOUT, errno);
+
+ owner = 123;
-+ ret = ioctl(fd, WINESYNC_IOC_KILL_OWNER, &owner);
++ ret = ioctl(fd, NTSYNC_IOC_KILL_OWNER, &owner);
+ EXPECT_EQ(0, ret);
+
+ ret = wait_any(fd, 2, objs, 456, &index);
@@ -2688,7 +3010,7 @@ index 801b776da5aa..5903061d38b6 100644
+
+ /* test waiting on the same object twice */
+ sem_args.count = 2;
-+ ret = ioctl(fd, WINESYNC_IOC_PUT_SEM, &sem_args);
++ ret = ioctl(fd, NTSYNC_IOC_PUT_SEM, &sem_args);
+ EXPECT_EQ(0, ret);
+ EXPECT_EQ(0, sem_args.count);
+
@@ -2702,9 +3024,9 @@ index 801b776da5aa..5903061d38b6 100644
+ EXPECT_EQ(-1, ret);
+ EXPECT_EQ(ETIMEDOUT, errno);
+
-+ ret = ioctl(fd, WINESYNC_IOC_DELETE, &sem_args.sem);
++ ret = ioctl(fd, NTSYNC_IOC_DELETE, &sem_args.sem);
+ EXPECT_EQ(0, ret);
-+ ret = ioctl(fd, WINESYNC_IOC_DELETE, &mutex_args.mutex);
++ ret = ioctl(fd, NTSYNC_IOC_DELETE, &mutex_args.mutex);
+ EXPECT_EQ(0, ret);
+
+ close(fd);
@@ -2712,22 +3034,22 @@ index 801b776da5aa..5903061d38b6 100644
+
TEST_HARNESS_MAIN
--
-2.36.0
+2.43.0
-From 17f55215ea56e925369e2eec7eaead604a273e34 Mon Sep 17 00:00:00 2001
-From: Zebediah Figura <zfigura@codeweavers.com>
+From 4610258d640a5bd75b7482b92cb74c4ffba58b84 Mon Sep 17 00:00:00 2001
+From: Elizabeth Figura <zfigura@codeweavers.com>
Date: Fri, 5 Mar 2021 12:08:25 -0600
-Subject: [PATCH 16/34] selftests: winesync: Add some tests for
+Subject: [PATCH 21/32] selftests: ntsync: Add some tests for
WINESYNC_IOC_WAIT_ALL.
---
- .../selftests/drivers/winesync/winesync.c | 104 +++++++++++++++++-
+ .../testing/selftests/drivers/ntsync/ntsync.c | 104 +++++++++++++++++-
1 file changed, 101 insertions(+), 3 deletions(-)
-diff --git a/tools/testing/selftests/drivers/winesync/winesync.c b/tools/testing/selftests/drivers/winesync/winesync.c
-index 5903061d38b6..0718219f54bf 100644
---- a/tools/testing/selftests/drivers/winesync/winesync.c
-+++ b/tools/testing/selftests/drivers/winesync/winesync.c
+diff --git a/tools/testing/selftests/drivers/ntsync/ntsync.c b/tools/testing/selftests/drivers/ntsync/ntsync.c
+index 8ae930e7a601..586e798d3228 100644
+--- a/tools/testing/selftests/drivers/ntsync/ntsync.c
++++ b/tools/testing/selftests/drivers/ntsync/ntsync.c
@@ -85,8 +85,8 @@ static int put_mutex(int fd, __u32 mutex, __u32 owner, __u32 *count)
return ret;
}
@@ -2737,13 +3059,13 @@ index 5903061d38b6..0718219f54bf 100644
+static int wait_objs(int fd, unsigned long request, __u32 count,
+ const __u32 *objs, __u32 owner, __u32 *index)
{
- struct winesync_wait_args args = {0};
+ struct ntsync_wait_args args = {0};
struct timespec timeout;
@@ -99,11 +99,23 @@ static int wait_any(int fd, __u32 count, const __u32 *objs, __u32 owner,
args.objs = (uintptr_t)objs;
args.owner = owner;
args.index = 0xdeadbeef;
-- ret = ioctl(fd, WINESYNC_IOC_WAIT_ANY, &args);
+- ret = ioctl(fd, NTSYNC_IOC_WAIT_ANY, &args);
+ ret = ioctl(fd, request, &args);
*index = args.index;
return ret;
@@ -2752,43 +3074,43 @@ index 5903061d38b6..0718219f54bf 100644
+static int wait_any(int fd, __u32 count, const __u32 *objs,
+ __u32 owner, __u32 *index)
+{
-+ return wait_objs(fd, WINESYNC_IOC_WAIT_ANY, count, objs, owner, index);
++ return wait_objs(fd, NTSYNC_IOC_WAIT_ANY, count, objs, owner, index);
+}
+
+static int wait_all(int fd, __u32 count, const __u32 *objs,
+ __u32 owner, __u32 *index)
+{
-+ return wait_objs(fd, WINESYNC_IOC_WAIT_ALL, count, objs, owner, index);
++ return wait_objs(fd, NTSYNC_IOC_WAIT_ALL, count, objs, owner, index);
+}
+
TEST(semaphore_state)
{
- struct winesync_sem_args sem_args;
+ struct ntsync_sem_args sem_args;
@@ -445,4 +457,90 @@ TEST(test_wait_any)
close(fd);
}
+TEST(test_wait_all)
+{
-+ struct winesync_mutex_args mutex_args = {0};
-+ struct winesync_sem_args sem_args = {0};
++ struct ntsync_mutex_args mutex_args = {0};
++ struct ntsync_sem_args sem_args = {0};
+ __u32 objs[2], owner, index;
+ int fd, ret;
+
-+ fd = open("/dev/winesync", O_CLOEXEC | O_RDONLY);
++ fd = open("/dev/ntsync", O_CLOEXEC | O_RDONLY);
+ ASSERT_LE(0, fd);
+
+ sem_args.count = 2;
+ sem_args.max = 3;
+ sem_args.sem = 0xdeadbeef;
-+ ret = ioctl(fd, WINESYNC_IOC_CREATE_SEM, &sem_args);
++ ret = ioctl(fd, NTSYNC_IOC_CREATE_SEM, &sem_args);
+ EXPECT_EQ(0, ret);
+ EXPECT_NE(0xdeadbeef, sem_args.sem);
+
+ mutex_args.owner = 0;
+ mutex_args.count = 0;
+ mutex_args.mutex = 0xdeadbeef;
-+ ret = ioctl(fd, WINESYNC_IOC_CREATE_MUTEX, &mutex_args);
++ ret = ioctl(fd, NTSYNC_IOC_CREATE_MUTEX, &mutex_args);
+ EXPECT_EQ(0, ret);
+ EXPECT_NE(0xdeadbeef, mutex_args.mutex);
+
@@ -2820,7 +3142,7 @@ index 5903061d38b6..0718219f54bf 100644
+ check_mutex_state(fd, mutex_args.mutex, 2, 123);
+
+ sem_args.count = 3;
-+ ret = ioctl(fd, WINESYNC_IOC_PUT_SEM, &sem_args);
++ ret = ioctl(fd, NTSYNC_IOC_PUT_SEM, &sem_args);
+ EXPECT_EQ(0, ret);
+ EXPECT_EQ(0, sem_args.count);
+
@@ -2831,7 +3153,7 @@ index 5903061d38b6..0718219f54bf 100644
+ check_mutex_state(fd, mutex_args.mutex, 3, 123);
+
+ owner = 123;
-+ ret = ioctl(fd, WINESYNC_IOC_KILL_OWNER, &owner);
++ ret = ioctl(fd, NTSYNC_IOC_KILL_OWNER, &owner);
+ EXPECT_EQ(0, ret);
+
+ ret = wait_all(fd, 2, objs, 123, &index);
@@ -2846,9 +3168,9 @@ index 5903061d38b6..0718219f54bf 100644
+ EXPECT_EQ(-1, ret);
+ EXPECT_EQ(EINVAL, errno);
+
-+ ret = ioctl(fd, WINESYNC_IOC_DELETE, &sem_args.sem);
++ ret = ioctl(fd, NTSYNC_IOC_DELETE, &sem_args.sem);
+ EXPECT_EQ(0, ret);
-+ ret = ioctl(fd, WINESYNC_IOC_DELETE, &mutex_args.mutex);
++ ret = ioctl(fd, NTSYNC_IOC_DELETE, &mutex_args.mutex);
+ EXPECT_EQ(0, ret);
+
+ close(fd);
@@ -2856,114 +3178,114 @@ index 5903061d38b6..0718219f54bf 100644
+
TEST_HARNESS_MAIN
--
-2.36.0
+2.43.0
-From 6d07a2265d06d3f0af6fe2d9874762fb2e922488 Mon Sep 17 00:00:00 2001
-From: Zebediah Figura <zfigura@codeweavers.com>
+From a18ca868f284f8eec745aec2346b2ff138370473 Mon Sep 17 00:00:00 2001
+From: Elizabeth Figura <zfigura@codeweavers.com>
Date: Fri, 5 Mar 2021 12:08:54 -0600
-Subject: [PATCH 17/34] selftests: winesync: Add some tests for invalid object
+Subject: [PATCH 22/32] selftests: ntsync: Add some tests for invalid object
handling.
---
- .../selftests/drivers/winesync/winesync.c | 93 +++++++++++++++++++
+ .../testing/selftests/drivers/ntsync/ntsync.c | 93 +++++++++++++++++++
1 file changed, 93 insertions(+)
-diff --git a/tools/testing/selftests/drivers/winesync/winesync.c b/tools/testing/selftests/drivers/winesync/winesync.c
-index 0718219f54bf..8a9fb496f5e0 100644
---- a/tools/testing/selftests/drivers/winesync/winesync.c
-+++ b/tools/testing/selftests/drivers/winesync/winesync.c
+diff --git a/tools/testing/selftests/drivers/ntsync/ntsync.c b/tools/testing/selftests/drivers/ntsync/ntsync.c
+index 586e798d3228..ac24a94f2518 100644
+--- a/tools/testing/selftests/drivers/ntsync/ntsync.c
++++ b/tools/testing/selftests/drivers/ntsync/ntsync.c
@@ -543,4 +543,97 @@ TEST(test_wait_all)
close(fd);
}
+TEST(invalid_objects)
+{
-+ struct winesync_mutex_args mutex_args = {0};
-+ struct winesync_wait_args wait_args = {0};
-+ struct winesync_sem_args sem_args = {0};
++ struct ntsync_mutex_args mutex_args = {0};
++ struct ntsync_wait_args wait_args = {0};
++ struct ntsync_sem_args sem_args = {0};
+ __u32 objs[2] = {0};
+ int fd, ret;
+
-+ fd = open("/dev/winesync", O_CLOEXEC | O_RDONLY);
++ fd = open("/dev/ntsync", O_CLOEXEC | O_RDONLY);
+ ASSERT_LE(0, fd);
+
-+ ret = ioctl(fd, WINESYNC_IOC_PUT_SEM, &sem_args);
++ ret = ioctl(fd, NTSYNC_IOC_PUT_SEM, &sem_args);
+ EXPECT_EQ(-1, ret);
+ EXPECT_EQ(EINVAL, errno);
+
-+ ret = ioctl(fd, WINESYNC_IOC_READ_SEM, &sem_args);
++ ret = ioctl(fd, NTSYNC_IOC_READ_SEM, &sem_args);
+ EXPECT_EQ(-1, ret);
+ EXPECT_EQ(EINVAL, errno);
+
-+ ret = ioctl(fd, WINESYNC_IOC_PUT_MUTEX, &mutex_args);
++ ret = ioctl(fd, NTSYNC_IOC_PUT_MUTEX, &mutex_args);
+ EXPECT_EQ(-1, ret);
+ EXPECT_EQ(EINVAL, errno);
+
-+ ret = ioctl(fd, WINESYNC_IOC_READ_MUTEX, &mutex_args);
++ ret = ioctl(fd, NTSYNC_IOC_READ_MUTEX, &mutex_args);
+ EXPECT_EQ(-1, ret);
+ EXPECT_EQ(EINVAL, errno);
+
+ wait_args.objs = (uintptr_t)objs;
+ wait_args.count = 1;
-+ ret = ioctl(fd, WINESYNC_IOC_WAIT_ANY, &wait_args);
++ ret = ioctl(fd, NTSYNC_IOC_WAIT_ANY, &wait_args);
+ EXPECT_EQ(-1, ret);
+ EXPECT_EQ(EINVAL, errno);
-+ ret = ioctl(fd, WINESYNC_IOC_WAIT_ALL, &wait_args);
++ ret = ioctl(fd, NTSYNC_IOC_WAIT_ALL, &wait_args);
+ EXPECT_EQ(-1, ret);
+ EXPECT_EQ(EINVAL, errno);
+
-+ ret = ioctl(fd, WINESYNC_IOC_DELETE, &objs[0]);
++ ret = ioctl(fd, NTSYNC_IOC_DELETE, &objs[0]);
+ EXPECT_EQ(-1, ret);
+ EXPECT_EQ(EINVAL, errno);
+
+ sem_args.max = 1;
-+ ret = ioctl(fd, WINESYNC_IOC_CREATE_SEM, &sem_args);
++ ret = ioctl(fd, NTSYNC_IOC_CREATE_SEM, &sem_args);
+ EXPECT_EQ(0, ret);
+
+ mutex_args.mutex = sem_args.sem;
-+ ret = ioctl(fd, WINESYNC_IOC_PUT_MUTEX, &mutex_args);
++ ret = ioctl(fd, NTSYNC_IOC_PUT_MUTEX, &mutex_args);
+ EXPECT_EQ(-1, ret);
+ EXPECT_EQ(EINVAL, errno);
+
-+ ret = ioctl(fd, WINESYNC_IOC_READ_MUTEX, &mutex_args);
++ ret = ioctl(fd, NTSYNC_IOC_READ_MUTEX, &mutex_args);
+ EXPECT_EQ(-1, ret);
+ EXPECT_EQ(EINVAL, errno);
+
+ objs[0] = sem_args.sem;
+ objs[1] = sem_args.sem + 1;
+ wait_args.count = 2;
-+ ret = ioctl(fd, WINESYNC_IOC_WAIT_ANY, &wait_args);
++ ret = ioctl(fd, NTSYNC_IOC_WAIT_ANY, &wait_args);
+ EXPECT_EQ(-1, ret);
+ EXPECT_EQ(EINVAL, errno);
-+ ret = ioctl(fd, WINESYNC_IOC_WAIT_ALL, &wait_args);
++ ret = ioctl(fd, NTSYNC_IOC_WAIT_ALL, &wait_args);
+ EXPECT_EQ(-1, ret);
+ EXPECT_EQ(EINVAL, errno);
+
+ objs[0] = sem_args.sem + 1;
+ objs[1] = sem_args.sem;
-+ ret = ioctl(fd, WINESYNC_IOC_WAIT_ANY, &wait_args);
++ ret = ioctl(fd, NTSYNC_IOC_WAIT_ANY, &wait_args);
+ EXPECT_EQ(-1, ret);
+ EXPECT_EQ(EINVAL, errno);
-+ ret = ioctl(fd, WINESYNC_IOC_WAIT_ALL, &wait_args);
++ ret = ioctl(fd, NTSYNC_IOC_WAIT_ALL, &wait_args);
+ EXPECT_EQ(-1, ret);
+ EXPECT_EQ(EINVAL, errno);
+
-+ ret = ioctl(fd, WINESYNC_IOC_DELETE, &sem_args.sem);
++ ret = ioctl(fd, NTSYNC_IOC_DELETE, &sem_args.sem);
+ EXPECT_EQ(0, ret);
+
-+ ret = ioctl(fd, WINESYNC_IOC_CREATE_MUTEX, &mutex_args);
++ ret = ioctl(fd, NTSYNC_IOC_CREATE_MUTEX, &mutex_args);
+ EXPECT_EQ(0, ret);
+
+ sem_args.sem = mutex_args.mutex;
-+ ret = ioctl(fd, WINESYNC_IOC_PUT_SEM, &sem_args);
++ ret = ioctl(fd, NTSYNC_IOC_PUT_SEM, &sem_args);
+ EXPECT_EQ(-1, ret);
+ EXPECT_EQ(EINVAL, errno);
+
-+ ret = ioctl(fd, WINESYNC_IOC_READ_SEM, &sem_args);
++ ret = ioctl(fd, NTSYNC_IOC_READ_SEM, &sem_args);
+ EXPECT_EQ(-1, ret);
+ EXPECT_EQ(EINVAL, errno);
+
-+ ret = ioctl(fd, WINESYNC_IOC_DELETE, &mutex_args.mutex);
++ ret = ioctl(fd, NTSYNC_IOC_DELETE, &mutex_args.mutex);
+ EXPECT_EQ(0, ret);
+
+ close(fd);
@@ -2971,22 +3293,22 @@ index 0718219f54bf..8a9fb496f5e0 100644
+
TEST_HARNESS_MAIN
--
-2.36.0
+2.43.0
-From fafaf63d58b1f8ae3644ec5850c170bce6f6b5d2 Mon Sep 17 00:00:00 2001
-From: Zebediah Figura <zfigura@codeweavers.com>
+From e49d10455ebe2a5d056523a225b8b179b1da932a Mon Sep 17 00:00:00 2001
+From: Elizabeth Figura <zfigura@codeweavers.com>
Date: Fri, 5 Mar 2021 12:09:32 -0600
-Subject: [PATCH 18/34] selftests: winesync: Add some tests for wakeup
- signaling with WINESYNC_IOC_WAIT_ANY.
+Subject: [PATCH 23/32] selftests: ntsync: Add some tests for wakeup signaling
+ with WINESYNC_IOC_WAIT_ANY.
---
- .../selftests/drivers/winesync/winesync.c | 154 ++++++++++++++++++
+ .../testing/selftests/drivers/ntsync/ntsync.c | 154 ++++++++++++++++++
1 file changed, 154 insertions(+)
-diff --git a/tools/testing/selftests/drivers/winesync/winesync.c b/tools/testing/selftests/drivers/winesync/winesync.c
-index 8a9fb496f5e0..04855df00894 100644
---- a/tools/testing/selftests/drivers/winesync/winesync.c
-+++ b/tools/testing/selftests/drivers/winesync/winesync.c
+diff --git a/tools/testing/selftests/drivers/ntsync/ntsync.c b/tools/testing/selftests/drivers/ntsync/ntsync.c
+index ac24a94f2518..919cabc3ba5e 100644
+--- a/tools/testing/selftests/drivers/ntsync/ntsync.c
++++ b/tools/testing/selftests/drivers/ntsync/ntsync.c
@@ -636,4 +636,158 @@ TEST(invalid_objects)
close(fd);
}
@@ -3001,7 +3323,7 @@ index 8a9fb496f5e0..04855df00894 100644
+{
+ int fd;
+ unsigned long request;
-+ struct winesync_wait_args *args;
++ struct ntsync_wait_args *args;
+ int ret;
+ int err;
+};
@@ -3033,29 +3355,29 @@ index 8a9fb496f5e0..04855df00894 100644
+
+TEST(wake_any)
+{
-+ struct winesync_mutex_args mutex_args = {0};
-+ struct winesync_wait_args wait_args = {0};
-+ struct winesync_sem_args sem_args = {0};
++ struct ntsync_mutex_args mutex_args = {0};
++ struct ntsync_wait_args wait_args = {0};
++ struct ntsync_sem_args sem_args = {0};
+ struct wait_args thread_args;
+ __u32 objs[2], count, index;
+ struct timespec timeout;
+ pthread_t thread;
+ int fd, ret;
+
-+ fd = open("/dev/winesync", O_CLOEXEC | O_RDONLY);
++ fd = open("/dev/ntsync", O_CLOEXEC | O_RDONLY);
+ ASSERT_LE(0, fd);
+
+ sem_args.count = 0;
+ sem_args.max = 3;
+ sem_args.sem = 0xdeadbeef;
-+ ret = ioctl(fd, WINESYNC_IOC_CREATE_SEM, &sem_args);
++ ret = ioctl(fd, NTSYNC_IOC_CREATE_SEM, &sem_args);
+ EXPECT_EQ(0, ret);
+ EXPECT_NE(0xdeadbeef, sem_args.sem);
+
+ mutex_args.owner = 123;
+ mutex_args.count = 1;
+ mutex_args.mutex = 0xdeadbeef;
-+ ret = ioctl(fd, WINESYNC_IOC_CREATE_MUTEX, &mutex_args);
++ ret = ioctl(fd, NTSYNC_IOC_CREATE_MUTEX, &mutex_args);
+ EXPECT_EQ(0, ret);
+ EXPECT_NE(0xdeadbeef, mutex_args.mutex);
+
@@ -3072,7 +3394,7 @@ index 8a9fb496f5e0..04855df00894 100644
+ wait_args.index = 0xdeadbeef;
+ thread_args.fd = fd;
+ thread_args.args = &wait_args;
-+ thread_args.request = WINESYNC_IOC_WAIT_ANY;
++ thread_args.request = NTSYNC_IOC_WAIT_ANY;
+ ret = pthread_create(&thread, NULL, wait_thread, &thread_args);
+ EXPECT_EQ(0, ret);
+
@@ -3080,7 +3402,7 @@ index 8a9fb496f5e0..04855df00894 100644
+ EXPECT_EQ(ETIMEDOUT, ret);
+
+ sem_args.count = 1;
-+ ret = ioctl(fd, WINESYNC_IOC_PUT_SEM, &sem_args);
++ ret = ioctl(fd, NTSYNC_IOC_PUT_SEM, &sem_args);
+ EXPECT_EQ(0, ret);
+ EXPECT_EQ(0, sem_args.count);
+ check_sem_state(fd, sem_args.sem, 0, 3);
@@ -3132,9 +3454,9 @@ index 8a9fb496f5e0..04855df00894 100644
+ ret = wait_for_thread(thread, 100);
+ EXPECT_EQ(ETIMEDOUT, ret);
+
-+ ret = ioctl(fd, WINESYNC_IOC_DELETE, &sem_args.sem);
++ ret = ioctl(fd, NTSYNC_IOC_DELETE, &sem_args.sem);
+ EXPECT_EQ(0, ret);
-+ ret = ioctl(fd, WINESYNC_IOC_DELETE, &mutex_args.mutex);
++ ret = ioctl(fd, NTSYNC_IOC_DELETE, &mutex_args.mutex);
+ EXPECT_EQ(0, ret);
+
+ ret = wait_for_thread(thread, 200);
@@ -3147,51 +3469,51 @@ index 8a9fb496f5e0..04855df00894 100644
+
TEST_HARNESS_MAIN
--
-2.36.0
+2.43.0
-From c1916abd720dc30c3dc1972fd9a4d69844e8ffbd Mon Sep 17 00:00:00 2001
-From: Zebediah Figura <zfigura@codeweavers.com>
+From a9f683caedb447a30b28a3ebb3d8fc597fe26d73 Mon Sep 17 00:00:00 2001
+From: Elizabeth Figura <zfigura@codeweavers.com>
Date: Fri, 5 Mar 2021 12:09:36 -0600
-Subject: [PATCH 19/34] selftests: winesync: Add some tests for wakeup
- signaling with WINESYNC_IOC_WAIT_ALL.
+Subject: [PATCH 24/32] selftests: ntsync: Add some tests for wakeup signaling
+ with WINESYNC_IOC_WAIT_ALL.
---
- .../selftests/drivers/winesync/winesync.c | 102 ++++++++++++++++++
+ .../testing/selftests/drivers/ntsync/ntsync.c | 102 ++++++++++++++++++
1 file changed, 102 insertions(+)
-diff --git a/tools/testing/selftests/drivers/winesync/winesync.c b/tools/testing/selftests/drivers/winesync/winesync.c
-index 04855df00894..ad6d0f9a2a35 100644
---- a/tools/testing/selftests/drivers/winesync/winesync.c
-+++ b/tools/testing/selftests/drivers/winesync/winesync.c
+diff --git a/tools/testing/selftests/drivers/ntsync/ntsync.c b/tools/testing/selftests/drivers/ntsync/ntsync.c
+index 919cabc3ba5e..3dbae7c8ac1f 100644
+--- a/tools/testing/selftests/drivers/ntsync/ntsync.c
++++ b/tools/testing/selftests/drivers/ntsync/ntsync.c
@@ -790,4 +790,106 @@ TEST(wake_any)
close(fd);
}
+TEST(wake_all)
+{
-+ struct winesync_mutex_args mutex_args = {0};
-+ struct winesync_wait_args wait_args = {0};
-+ struct winesync_sem_args sem_args = {0};
++ struct ntsync_mutex_args mutex_args = {0};
++ struct ntsync_wait_args wait_args = {0};
++ struct ntsync_sem_args sem_args = {0};
+ struct wait_args thread_args;
+ __u32 objs[2], count, index;
+ struct timespec timeout;
+ pthread_t thread;
+ int fd, ret;
+
-+ fd = open("/dev/winesync", O_CLOEXEC | O_RDONLY);
++ fd = open("/dev/ntsync", O_CLOEXEC | O_RDONLY);
+ ASSERT_LE(0, fd);
+
+ sem_args.count = 0;
+ sem_args.max = 3;
+ sem_args.sem = 0xdeadbeef;
-+ ret = ioctl(fd, WINESYNC_IOC_CREATE_SEM, &sem_args);
++ ret = ioctl(fd, NTSYNC_IOC_CREATE_SEM, &sem_args);
+ EXPECT_EQ(0, ret);
+ EXPECT_NE(0xdeadbeef, sem_args.sem);
+
+ mutex_args.owner = 123;
+ mutex_args.count = 1;
+ mutex_args.mutex = 0xdeadbeef;
-+ ret = ioctl(fd, WINESYNC_IOC_CREATE_MUTEX, &mutex_args);
++ ret = ioctl(fd, NTSYNC_IOC_CREATE_MUTEX, &mutex_args);
+ EXPECT_EQ(0, ret);
+ EXPECT_NE(0xdeadbeef, mutex_args.mutex);
+
@@ -3205,7 +3527,7 @@ index 04855df00894..ad6d0f9a2a35 100644
+ wait_args.owner = 456;
+ thread_args.fd = fd;
+ thread_args.args = &wait_args;
-+ thread_args.request = WINESYNC_IOC_WAIT_ALL;
++ thread_args.request = NTSYNC_IOC_WAIT_ALL;
+ ret = pthread_create(&thread, NULL, wait_thread, &thread_args);
+ EXPECT_EQ(0, ret);
+
@@ -3213,7 +3535,7 @@ index 04855df00894..ad6d0f9a2a35 100644
+ EXPECT_EQ(ETIMEDOUT, ret);
+
+ sem_args.count = 1;
-+ ret = ioctl(fd, WINESYNC_IOC_PUT_SEM, &sem_args);
++ ret = ioctl(fd, NTSYNC_IOC_PUT_SEM, &sem_args);
+ EXPECT_EQ(0, ret);
+ EXPECT_EQ(0, sem_args.count);
+
@@ -3236,7 +3558,7 @@ index 04855df00894..ad6d0f9a2a35 100644
+ check_mutex_state(fd, mutex_args.mutex, 0, 0);
+
+ sem_args.count = 2;
-+ ret = ioctl(fd, WINESYNC_IOC_PUT_SEM, &sem_args);
++ ret = ioctl(fd, NTSYNC_IOC_PUT_SEM, &sem_args);
+ EXPECT_EQ(0, ret);
+ EXPECT_EQ(0, sem_args.count);
+ check_sem_state(fd, sem_args.sem, 1, 3);
@@ -3256,9 +3578,9 @@ index 04855df00894..ad6d0f9a2a35 100644
+ ret = wait_for_thread(thread, 100);
+ EXPECT_EQ(ETIMEDOUT, ret);
+
-+ ret = ioctl(fd, WINESYNC_IOC_DELETE, &sem_args.sem);
++ ret = ioctl(fd, NTSYNC_IOC_DELETE, &sem_args.sem);
+ EXPECT_EQ(0, ret);
-+ ret = ioctl(fd, WINESYNC_IOC_DELETE, &mutex_args.mutex);
++ ret = ioctl(fd, NTSYNC_IOC_DELETE, &mutex_args.mutex);
+ EXPECT_EQ(0, ret);
+
+ ret = wait_for_thread(thread, 200);
@@ -3271,539 +3593,35 @@ index 04855df00894..ad6d0f9a2a35 100644
+
TEST_HARNESS_MAIN
--
-2.36.0
-
-From 30ea479d690ddcc7eed1b580843f54ab7910d6bd Mon Sep 17 00:00:00 2001
-From: Zebediah Figura <zfigura@codeweavers.com>
-Date: Fri, 5 Mar 2021 12:22:55 -0600
-Subject: [PATCH 20/34] maintainers: Add an entry for winesync.
-
----
- MAINTAINERS | 9 +++++++++
- 1 file changed, 9 insertions(+)
-
-diff --git a/MAINTAINERS b/MAINTAINERS
-index 72b9654f764c..ff31beb17835 100644
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -23391,6 +23391,15 @@
- S: Maintained
- F: drivers/media/rc/winbond-cir.c
-
-+WINESYNC SYNCHRONIZATION PRIMITIVE DRIVER
-+M: Zebediah Figura <zfigura@codeweavers.com>
-+L: wine-devel@winehq.org
-+S: Supported
-+F: Documentation/userspace-api/winesync.rst
-+F: drivers/misc/winesync.c
-+F: include/uapi/linux/winesync.h
-+F: tools/testing/selftests/drivers/winesync/
-+
- WINSYSTEMS EBC-C384 WATCHDOG DRIVER
- L: linux-watchdog@vger.kernel.org
- S: Orphan
---
-2.37.3
-
-From 4e6e34339182f13972e7b906c0bd0dde74eda3d7 Mon Sep 17 00:00:00 2001
-From: Zebediah Figura <zfigura@codeweavers.com>
-Date: Wed, 19 Jan 2022 18:21:03 -0600
-Subject: [PATCH 21/34] winesync: Introduce WINESYNC_IOC_CREATE_EVENT.
-
----
- drivers/misc/winesync.c | 65 +++++++++++++++++++++++++++++++++++
- include/uapi/linux/winesync.h | 8 +++++
- 2 files changed, 73 insertions(+)
-
-diff --git a/drivers/misc/winesync.c b/drivers/misc/winesync.c
-index eae272663abe..eaba41510784 100644
---- a/drivers/misc/winesync.c
-+++ b/drivers/misc/winesync.c
-@@ -17,6 +17,7 @@
- enum winesync_type {
- WINESYNC_TYPE_SEM,
- WINESYNC_TYPE_MUTEX,
-+ WINESYNC_TYPE_EVENT,
- };
-
- struct winesync_obj {
-@@ -66,6 +67,10 @@ struct winesync_obj {
- __u32 owner;
- bool ownerdead;
- } mutex;
-+ struct {
-+ bool manual;
-+ bool signaled;
-+ } event;
- } u;
- };
-
-@@ -199,6 +204,8 @@ static bool is_signaled(struct winesync_obj *obj, __u32 owner)
- if (obj->u.mutex.owner && obj->u.mutex.owner != owner)
- return false;
- return obj->u.mutex.count < UINT_MAX;
-+ case WINESYNC_TYPE_EVENT:
-+ return obj->u.event.signaled;
- }
-
- WARN(1, "bad object type %#x\n", obj->type);
-@@ -248,6 +255,10 @@ static void try_wake_all(struct winesync_device *dev, struct winesync_q *q,
- obj->u.mutex.count++;
- obj->u.mutex.owner = q->owner;
- break;
-+ case WINESYNC_TYPE_EVENT:
-+ if (!obj->u.event.manual)
-+ obj->u.event.signaled = false;
-+ break;
- }
- }
- wake_up_process(q->task);
-@@ -315,6 +326,26 @@ static void try_wake_any_mutex(struct winesync_obj *mutex)
- }
- }
-
-+static void try_wake_any_event(struct winesync_obj *event)
-+{
-+ struct winesync_q_entry *entry;
-+
-+ lockdep_assert_held(&event->lock);
-+
-+ list_for_each_entry(entry, &event->any_waiters, node) {
-+ struct winesync_q *q = entry->q;
-+
-+ if (!event->u.event.signaled)
-+ break;
-+
-+ if (atomic_cmpxchg(&q->signaled, -1, entry->index) == -1) {
-+ if (!event->u.event.manual)
-+ event->u.event.signaled = false;
-+ wake_up_process(q->task);
-+ }
-+ }
-+}
-+
- static int winesync_create_sem(struct winesync_device *dev, void __user *argp)
- {
- struct winesync_sem_args __user *user_args = argp;
-@@ -379,6 +410,35 @@ static int winesync_create_mutex(struct winesync_device *dev, void __user *argp)
- return put_user(id, &user_args->mutex);
- }
-
-+static int winesync_create_event(struct winesync_device *dev, void __user *argp)
-+{
-+ struct winesync_event_args __user *user_args = argp;
-+ struct winesync_event_args args;
-+ struct winesync_obj *event;
-+ __u32 id;
-+ int ret;
-+
-+ if (copy_from_user(&args, argp, sizeof(args)))
-+ return -EFAULT;
-+
-+ event = kzalloc(sizeof(*event), GFP_KERNEL);
-+ if (!event)
-+ return -ENOMEM;
-+
-+ init_obj(event);
-+ event->type = WINESYNC_TYPE_EVENT;
-+ event->u.event.manual = args.manual;
-+ event->u.event.signaled = args.signaled;
-+
-+ ret = xa_alloc(&dev->objects, &id, event, xa_limit_32b, GFP_KERNEL);
-+ if (ret < 0) {
-+ kfree(event);
-+ return ret;
-+ }
-+
-+ return put_user(id, &user_args->event);
-+}
-+
- static int winesync_delete(struct winesync_device *dev, void __user *argp)
- {
- struct winesync_obj *obj;
-@@ -760,6 +820,9 @@ static void try_wake_any_obj(struct winesync_obj *obj)
- case WINESYNC_TYPE_MUTEX:
- try_wake_any_mutex(obj);
- break;
-+ case WINESYNC_TYPE_EVENT:
-+ try_wake_any_event(obj);
-+ break;
- }
- }
-
-@@ -925,6 +988,8 @@ static long winesync_char_ioctl(struct file *file, unsigned int cmd,
- void __user *argp = (void __user *)parm;
-
- switch (cmd) {
-+ case WINESYNC_IOC_CREATE_EVENT:
-+ return winesync_create_event(dev, argp);
- case WINESYNC_IOC_CREATE_MUTEX:
- return winesync_create_mutex(dev, argp);
- case WINESYNC_IOC_CREATE_SEM:
-diff --git a/include/uapi/linux/winesync.h b/include/uapi/linux/winesync.h
-index 3371a303a927..3999407534e0 100644
---- a/include/uapi/linux/winesync.h
-+++ b/include/uapi/linux/winesync.h
-@@ -22,6 +22,12 @@ struct winesync_mutex_args {
- __u32 count;
- };
-
-+struct winesync_event_args {
-+ __u32 event;
-+ __u32 manual;
-+ __u32 signaled;
-+};
-+
- struct winesync_wait_args {
- __u64 timeout;
- __u64 objs;
-@@ -51,5 +57,7 @@ struct winesync_wait_args {
- struct winesync_sem_args)
- #define WINESYNC_IOC_READ_MUTEX _IOWR(WINESYNC_IOC_BASE, 9, \
- struct winesync_mutex_args)
-+#define WINESYNC_IOC_CREATE_EVENT _IOWR(WINESYNC_IOC_BASE, 10, \
-+ struct winesync_event_args)
-
- #endif
---
-2.36.0
+2.43.0
-From 92a843a6d77099e638d5513fb4093e42ba84a3a3 Mon Sep 17 00:00:00 2001
-From: Zebediah Figura <zfigura@codeweavers.com>
-Date: Wed, 19 Jan 2022 18:43:30 -0600
-Subject: [PATCH 22/34] winesync: Introduce WINESYNC_IOC_SET_EVENT.
-
----
- drivers/misc/winesync.c | 45 +++++++++++++++++++++++++++++++++++
- include/uapi/linux/winesync.h | 2 ++
- 2 files changed, 47 insertions(+)
-
-diff --git a/drivers/misc/winesync.c b/drivers/misc/winesync.c
-index eaba41510784..658ad7b80c29 100644
---- a/drivers/misc/winesync.c
-+++ b/drivers/misc/winesync.c
-@@ -704,6 +704,49 @@ static int winesync_kill_owner(struct winesync_device *dev, void __user *argp)
- return 0;
- }
-
-+static int winesync_set_event(struct winesync_device *dev, void __user *argp)
-+{
-+ struct winesync_event_args __user *user_args = argp;
-+ struct winesync_event_args args;
-+ struct winesync_obj *event;
-+ bool prev_state;
-+
-+ if (copy_from_user(&args, argp, sizeof(args)))
-+ return -EFAULT;
-+
-+ event = get_obj_typed(dev, args.event, WINESYNC_TYPE_EVENT);
-+ if (!event)
-+ return -EINVAL;
-+
-+ if (atomic_read(&event->all_hint) > 0) {
-+ spin_lock(&dev->wait_all_lock);
-+ spin_lock(&event->lock);
-+
-+ prev_state = event->u.event.signaled;
-+ event->u.event.signaled = true;
-+ try_wake_all_obj(dev, event);
-+ try_wake_any_event(event);
-+
-+ spin_unlock(&event->lock);
-+ spin_unlock(&dev->wait_all_lock);
-+ } else {
-+ spin_lock(&event->lock);
-+
-+ prev_state = event->u.event.signaled;
-+ event->u.event.signaled = true;
-+ try_wake_any_event(event);
-+
-+ spin_unlock(&event->lock);
-+ }
-+
-+ put_obj(event);
-+
-+ if (put_user(prev_state, &user_args->signaled))
-+ return -EFAULT;
-+
-+ return 0;
-+}
-+
- static int winesync_schedule(const struct winesync_q *q, ktime_t *timeout)
- {
- int ret = 0;
-@@ -1006,6 +1049,8 @@ static long winesync_char_ioctl(struct file *file, unsigned int cmd,
- return winesync_read_mutex(dev, argp);
- case WINESYNC_IOC_READ_SEM:
- return winesync_read_sem(dev, argp);
-+ case WINESYNC_IOC_SET_EVENT:
-+ return winesync_set_event(dev, argp);
- case WINESYNC_IOC_WAIT_ALL:
- return winesync_wait_all(dev, argp);
- case WINESYNC_IOC_WAIT_ANY:
-diff --git a/include/uapi/linux/winesync.h b/include/uapi/linux/winesync.h
-index 3999407534e0..34cd65d879a8 100644
---- a/include/uapi/linux/winesync.h
-+++ b/include/uapi/linux/winesync.h
-@@ -59,5 +59,7 @@ struct winesync_wait_args {
- struct winesync_mutex_args)
- #define WINESYNC_IOC_CREATE_EVENT _IOWR(WINESYNC_IOC_BASE, 10, \
- struct winesync_event_args)
-+#define WINESYNC_IOC_SET_EVENT _IOWR(WINESYNC_IOC_BASE, 11, \
-+ struct winesync_event_args)
-
- #endif
---
-2.36.0
-
-From 7abe646cd9c913b78156186e3a2d98715a0f3513 Mon Sep 17 00:00:00 2001
-From: Zebediah Figura <zfigura@codeweavers.com>
-Date: Wed, 19 Jan 2022 19:00:25 -0600
-Subject: [PATCH 23/34] winesync: Introduce WINESYNC_IOC_RESET_EVENT.
-
----
- drivers/misc/winesync.c | 31 +++++++++++++++++++++++++++++++
- include/uapi/linux/winesync.h | 2 ++
- 2 files changed, 33 insertions(+)
-
-diff --git a/drivers/misc/winesync.c b/drivers/misc/winesync.c
-index 658ad7b80c29..a93f173127f4 100644
---- a/drivers/misc/winesync.c
-+++ b/drivers/misc/winesync.c
-@@ -747,6 +747,35 @@ static int winesync_set_event(struct winesync_device *dev, void __user *argp)
- return 0;
- }
-
-+static int winesync_reset_event(struct winesync_device *dev, void __user *argp)
-+{
-+ struct winesync_event_args __user *user_args = argp;
-+ struct winesync_event_args args;
-+ struct winesync_obj *event;
-+ bool prev_state;
-+
-+ if (copy_from_user(&args, argp, sizeof(args)))
-+ return -EFAULT;
-+
-+ event = get_obj_typed(dev, args.event, WINESYNC_TYPE_EVENT);
-+ if (!event)
-+ return -EINVAL;
-+
-+ spin_lock(&event->lock);
-+
-+ prev_state = event->u.event.signaled;
-+ event->u.event.signaled = false;
-+
-+ spin_unlock(&event->lock);
-+
-+ put_obj(event);
-+
-+ if (put_user(prev_state, &user_args->signaled))
-+ return -EFAULT;
-+
-+ return 0;
-+}
-+
- static int winesync_schedule(const struct winesync_q *q, ktime_t *timeout)
- {
- int ret = 0;
-@@ -1049,6 +1078,8 @@ static long winesync_char_ioctl(struct file *file, unsigned int cmd,
- return winesync_read_mutex(dev, argp);
- case WINESYNC_IOC_READ_SEM:
- return winesync_read_sem(dev, argp);
-+ case WINESYNC_IOC_RESET_EVENT:
-+ return winesync_reset_event(dev, argp);
- case WINESYNC_IOC_SET_EVENT:
- return winesync_set_event(dev, argp);
- case WINESYNC_IOC_WAIT_ALL:
-diff --git a/include/uapi/linux/winesync.h b/include/uapi/linux/winesync.h
-index 34cd65d879a8..e71271fc44ba 100644
---- a/include/uapi/linux/winesync.h
-+++ b/include/uapi/linux/winesync.h
-@@ -61,5 +61,7 @@ struct winesync_wait_args {
- struct winesync_event_args)
- #define WINESYNC_IOC_SET_EVENT _IOWR(WINESYNC_IOC_BASE, 11, \
- struct winesync_event_args)
-+#define WINESYNC_IOC_RESET_EVENT _IOWR(WINESYNC_IOC_BASE, 12, \
-+ struct winesync_event_args)
-
- #endif
---
-2.36.0
-
-From 3ea6a631230c7b17d345e2249f5f72ad24c46a79 Mon Sep 17 00:00:00 2001
-From: Zebediah Figura <zfigura@codeweavers.com>
-Date: Wed, 19 Jan 2022 19:10:12 -0600
-Subject: [PATCH 24/34] winesync: Introduce WINESYNC_IOC_PULSE_EVENT.
-
----
- drivers/misc/winesync.c | 11 +++++++++--
- include/uapi/linux/winesync.h | 2 ++
- 2 files changed, 11 insertions(+), 2 deletions(-)
-
-diff --git a/drivers/misc/winesync.c b/drivers/misc/winesync.c
-index a93f173127f4..27d5baa457df 100644
---- a/drivers/misc/winesync.c
-+++ b/drivers/misc/winesync.c
-@@ -704,7 +704,8 @@ static int winesync_kill_owner(struct winesync_device *dev, void __user *argp)
- return 0;
- }
-
--static int winesync_set_event(struct winesync_device *dev, void __user *argp)
-+static int winesync_set_event(struct winesync_device *dev, void __user *argp,
-+ bool pulse)
- {
- struct winesync_event_args __user *user_args = argp;
- struct winesync_event_args args;
-@@ -726,6 +727,8 @@ static int winesync_set_event(struct winesync_device *dev, void __user *argp)
- event->u.event.signaled = true;
- try_wake_all_obj(dev, event);
- try_wake_any_event(event);
-+ if (pulse)
-+ event->u.event.signaled = false;
-
- spin_unlock(&event->lock);
- spin_unlock(&dev->wait_all_lock);
-@@ -735,6 +738,8 @@ static int winesync_set_event(struct winesync_device *dev, void __user *argp)
- prev_state = event->u.event.signaled;
- event->u.event.signaled = true;
- try_wake_any_event(event);
-+ if (pulse)
-+ event->u.event.signaled = false;
-
- spin_unlock(&event->lock);
- }
-@@ -1070,6 +1075,8 @@ static long winesync_char_ioctl(struct file *file, unsigned int cmd,
- return winesync_delete(dev, argp);
- case WINESYNC_IOC_KILL_OWNER:
- return winesync_kill_owner(dev, argp);
-+ case WINESYNC_IOC_PULSE_EVENT:
-+ return winesync_set_event(dev, argp, true);
- case WINESYNC_IOC_PUT_MUTEX:
- return winesync_put_mutex(dev, argp);
- case WINESYNC_IOC_PUT_SEM:
-@@ -1081,7 +1088,7 @@ static long winesync_char_ioctl(struct file *file, unsigned int cmd,
- case WINESYNC_IOC_RESET_EVENT:
- return winesync_reset_event(dev, argp);
- case WINESYNC_IOC_SET_EVENT:
-- return winesync_set_event(dev, argp);
-+ return winesync_set_event(dev, argp, false);
- case WINESYNC_IOC_WAIT_ALL:
- return winesync_wait_all(dev, argp);
- case WINESYNC_IOC_WAIT_ANY:
-diff --git a/include/uapi/linux/winesync.h b/include/uapi/linux/winesync.h
-index e71271fc44ba..7c09d0e9733c 100644
---- a/include/uapi/linux/winesync.h
-+++ b/include/uapi/linux/winesync.h
-@@ -63,5 +63,7 @@ struct winesync_wait_args {
- struct winesync_event_args)
- #define WINESYNC_IOC_RESET_EVENT _IOWR(WINESYNC_IOC_BASE, 12, \
- struct winesync_event_args)
-+#define WINESYNC_IOC_PULSE_EVENT _IOWR(WINESYNC_IOC_BASE, 13, \
-+ struct winesync_event_args)
-
- #endif
---
-2.36.0
-
-From 0fb972bb73385f9140f81a5f976b95ba750b73dd Mon Sep 17 00:00:00 2001
-From: Zebediah Figura <zfigura@codeweavers.com>
-Date: Wed, 19 Jan 2022 19:14:00 -0600
-Subject: [PATCH 25/34] winesync: Introduce WINESYNC_IOC_READ_EVENT.
-
----
- drivers/misc/winesync.c | 30 ++++++++++++++++++++++++++++++
- include/uapi/linux/winesync.h | 2 ++
- 2 files changed, 32 insertions(+)
-
-diff --git a/drivers/misc/winesync.c b/drivers/misc/winesync.c
-index 27d5baa457df..0f8a8a94eef8 100644
---- a/drivers/misc/winesync.c
-+++ b/drivers/misc/winesync.c
-@@ -639,6 +639,33 @@ static int winesync_read_mutex(struct winesync_device *dev, void __user *argp)
- return ret;
- }
-
-+static int winesync_read_event(struct winesync_device *dev, void __user *argp)
-+{
-+ struct winesync_event_args __user *user_args = argp;
-+ struct winesync_event_args args;
-+ struct winesync_obj *event;
-+ __u32 id;
-+
-+ if (get_user(id, &user_args->event))
-+ return -EFAULT;
-+
-+ event = get_obj_typed(dev, id, WINESYNC_TYPE_EVENT);
-+ if (!event)
-+ return -EINVAL;
-+
-+ args.event = id;
-+ spin_lock(&event->lock);
-+ args.manual = event->u.event.manual;
-+ args.signaled = event->u.event.signaled;
-+ spin_unlock(&event->lock);
-+
-+ put_obj(event);
-+
-+ if (copy_to_user(user_args, &args, sizeof(args)))
-+ return -EFAULT;
-+ return 0;
-+}
-+
- /*
- * Actually change the mutex state to mark its owner as dead.
- */
-@@ -1081,6 +1109,8 @@ static long winesync_char_ioctl(struct file *file, unsigned int cmd,
- return winesync_put_mutex(dev, argp);
- case WINESYNC_IOC_PUT_SEM:
- return winesync_put_sem(dev, argp);
-+ case WINESYNC_IOC_READ_EVENT:
-+ return winesync_read_event(dev, argp);
- case WINESYNC_IOC_READ_MUTEX:
- return winesync_read_mutex(dev, argp);
- case WINESYNC_IOC_READ_SEM:
-diff --git a/include/uapi/linux/winesync.h b/include/uapi/linux/winesync.h
-index 7c09d0e9733c..fb3788339ffe 100644
---- a/include/uapi/linux/winesync.h
-+++ b/include/uapi/linux/winesync.h
-@@ -65,5 +65,7 @@ struct winesync_wait_args {
- struct winesync_event_args)
- #define WINESYNC_IOC_PULSE_EVENT _IOWR(WINESYNC_IOC_BASE, 13, \
- struct winesync_event_args)
-+#define WINESYNC_IOC_READ_EVENT _IOWR(WINESYNC_IOC_BASE, 14, \
-+ struct winesync_event_args)
-
- #endif
---
-2.36.0
-
-From ae7648556c522595d288bc169bde503140a59db0 Mon Sep 17 00:00:00 2001
-From: Zebediah Figura <zfigura@codeweavers.com>
+From f56885c1a183947d3b1f5e11a80ce23c7f150e33 Mon Sep 17 00:00:00 2001
+From: Elizabeth Figura <zfigura@codeweavers.com>
Date: Wed, 19 Jan 2022 19:34:47 -0600
-Subject: [PATCH 26/34] selftests: winesync: Add some tests for manual-reset
+Subject: [PATCH 25/32] selftests: ntsync: Add some tests for manual-reset
event state.
---
- .../selftests/drivers/winesync/winesync.c | 92 +++++++++++++++++++
+ .../testing/selftests/drivers/ntsync/ntsync.c | 92 +++++++++++++++++++
1 file changed, 92 insertions(+)
-diff --git a/tools/testing/selftests/drivers/winesync/winesync.c b/tools/testing/selftests/drivers/winesync/winesync.c
-index ad6d0f9a2a35..7e99f09b113b 100644
---- a/tools/testing/selftests/drivers/winesync/winesync.c
-+++ b/tools/testing/selftests/drivers/winesync/winesync.c
+diff --git a/tools/testing/selftests/drivers/ntsync/ntsync.c b/tools/testing/selftests/drivers/ntsync/ntsync.c
+index 3dbae7c8ac1f..cbe4ed73ffb9 100644
+--- a/tools/testing/selftests/drivers/ntsync/ntsync.c
++++ b/tools/testing/selftests/drivers/ntsync/ntsync.c
@@ -85,6 +85,30 @@ static int put_mutex(int fd, __u32 mutex, __u32 owner, __u32 *count)
return ret;
}
+static int read_event_state(int fd, __u32 event, __u32 *signaled, __u32 *manual)
+{
-+ struct winesync_event_args args;
++ struct ntsync_event_args args;
+ int ret;
+
+ args.event = event;
+ args.signaled = 0xdeadbeef;
+ args.manual = 0xdeadbeef;
-+ ret = ioctl(fd, WINESYNC_IOC_READ_EVENT, &args);
++ ret = ioctl(fd, NTSYNC_IOC_READ_EVENT, &args);
+ *signaled = args.signaled;
+ *manual = args.manual;
+ return ret;
@@ -3828,28 +3646,28 @@ index ad6d0f9a2a35..7e99f09b113b 100644
+TEST(manual_event_state)
+{
-+ struct winesync_event_args event_args;
++ struct ntsync_event_args event_args;
+ __u32 index;
+ int fd, ret;
+
-+ fd = open("/dev/winesync", O_CLOEXEC | O_RDONLY);
++ fd = open("/dev/ntsync", O_CLOEXEC | O_RDONLY);
+ ASSERT_LE(0, fd);
+
+ event_args.manual = 1;
+ event_args.signaled = 0;
+ event_args.event = 0xdeadbeef;
-+ ret = ioctl(fd, WINESYNC_IOC_CREATE_EVENT, &event_args);
++ ret = ioctl(fd, NTSYNC_IOC_CREATE_EVENT, &event_args);
+ EXPECT_EQ(0, ret);
+ EXPECT_NE(0xdeadbeef, event_args.event);
+ check_event_state(fd, event_args.event, 0, 1);
+
+ event_args.signaled = 0xdeadbeef;
-+ ret = ioctl(fd, WINESYNC_IOC_SET_EVENT, &event_args);
++ ret = ioctl(fd, NTSYNC_IOC_SET_EVENT, &event_args);
+ EXPECT_EQ(0, ret);
+ EXPECT_EQ(0, event_args.signaled);
+ check_event_state(fd, event_args.event, 1, 1);
+
-+ ret = ioctl(fd, WINESYNC_IOC_SET_EVENT, &event_args);
++ ret = ioctl(fd, NTSYNC_IOC_SET_EVENT, &event_args);
+ EXPECT_EQ(0, ret);
+ EXPECT_EQ(1, event_args.signaled);
+ check_event_state(fd, event_args.event, 1, 1);
@@ -3860,12 +3678,12 @@ index ad6d0f9a2a35..7e99f09b113b 100644
+ check_event_state(fd, event_args.event, 1, 1);
+
+ event_args.signaled = 0xdeadbeef;
-+ ret = ioctl(fd, WINESYNC_IOC_RESET_EVENT, &event_args);
++ ret = ioctl(fd, NTSYNC_IOC_RESET_EVENT, &event_args);
+ EXPECT_EQ(0, ret);
+ EXPECT_EQ(1, event_args.signaled);
+ check_event_state(fd, event_args.event, 0, 1);
+
-+ ret = ioctl(fd, WINESYNC_IOC_RESET_EVENT, &event_args);
++ ret = ioctl(fd, NTSYNC_IOC_RESET_EVENT, &event_args);
+ EXPECT_EQ(0, ret);
+ EXPECT_EQ(0, event_args.signaled);
+ check_event_state(fd, event_args.event, 0, 1);
@@ -3874,21 +3692,21 @@ index ad6d0f9a2a35..7e99f09b113b 100644
+ EXPECT_EQ(-1, ret);
+ EXPECT_EQ(ETIMEDOUT, errno);
+
-+ ret = ioctl(fd, WINESYNC_IOC_SET_EVENT, &event_args);
++ ret = ioctl(fd, NTSYNC_IOC_SET_EVENT, &event_args);
+ EXPECT_EQ(0, ret);
+ EXPECT_EQ(0, event_args.signaled);
+
-+ ret = ioctl(fd, WINESYNC_IOC_PULSE_EVENT, &event_args);
++ ret = ioctl(fd, NTSYNC_IOC_PULSE_EVENT, &event_args);
+ EXPECT_EQ(0, ret);
+ EXPECT_EQ(1, event_args.signaled);
+ check_event_state(fd, event_args.event, 0, 1);
+
-+ ret = ioctl(fd, WINESYNC_IOC_PULSE_EVENT, &event_args);
++ ret = ioctl(fd, NTSYNC_IOC_PULSE_EVENT, &event_args);
+ EXPECT_EQ(0, ret);
+ EXPECT_EQ(0, event_args.signaled);
+ check_event_state(fd, event_args.event, 0, 1);
+
-+ ret = ioctl(fd, WINESYNC_IOC_DELETE, &event_args.event);
++ ret = ioctl(fd, NTSYNC_IOC_DELETE, &event_args.event);
+ EXPECT_EQ(0, ret);
+
+ close(fd);
@@ -3896,48 +3714,48 @@ index ad6d0f9a2a35..7e99f09b113b 100644
+
TEST(test_wait_any)
{
- struct winesync_mutex_args mutex_args = {0};
+ struct ntsync_mutex_args mutex_args = {0};
--
-2.36.0
+2.43.0
-From 5eeeb415ccc7e046fc71f20345bf8be20edfc1c4 Mon Sep 17 00:00:00 2001
-From: Zebediah Figura <zfigura@codeweavers.com>
+From d1e2db12a317942c72505085459dad6d64c8926a Mon Sep 17 00:00:00 2001
+From: Elizabeth Figura <zfigura@codeweavers.com>
Date: Wed, 19 Jan 2022 19:45:39 -0600
-Subject: [PATCH 27/34] selftests: winesync: Add some tests for auto-reset
- event state.
+Subject: [PATCH 26/32] selftests: ntsync: Add some tests for auto-reset event
+ state.
---
- .../selftests/drivers/winesync/winesync.c | 59 +++++++++++++++++++
+ .../testing/selftests/drivers/ntsync/ntsync.c | 59 +++++++++++++++++++
1 file changed, 59 insertions(+)
-diff --git a/tools/testing/selftests/drivers/winesync/winesync.c b/tools/testing/selftests/drivers/winesync/winesync.c
-index 7e99f09b113b..3a9ac69308af 100644
---- a/tools/testing/selftests/drivers/winesync/winesync.c
-+++ b/tools/testing/selftests/drivers/winesync/winesync.c
+diff --git a/tools/testing/selftests/drivers/ntsync/ntsync.c b/tools/testing/selftests/drivers/ntsync/ntsync.c
+index cbe4ed73ffb9..c158c15fc03e 100644
+--- a/tools/testing/selftests/drivers/ntsync/ntsync.c
++++ b/tools/testing/selftests/drivers/ntsync/ntsync.c
@@ -442,6 +442,65 @@ TEST(manual_event_state)
close(fd);
}
+TEST(auto_event_state)
+{
-+ struct winesync_event_args event_args;
++ struct ntsync_event_args event_args;
+ __u32 index;
+ int fd, ret;
+
-+ fd = open("/dev/winesync", O_CLOEXEC | O_RDONLY);
++ fd = open("/dev/ntsync", O_CLOEXEC | O_RDONLY);
+ ASSERT_LE(0, fd);
+
+ event_args.manual = 0;
+ event_args.signaled = 1;
+ event_args.event = 0xdeadbeef;
-+ ret = ioctl(fd, WINESYNC_IOC_CREATE_EVENT, &event_args);
++ ret = ioctl(fd, NTSYNC_IOC_CREATE_EVENT, &event_args);
+ EXPECT_EQ(0, ret);
+ EXPECT_NE(0xdeadbeef, event_args.event);
+
+ check_event_state(fd, event_args.event, 1, 0);
+
+ event_args.signaled = 0xdeadbeef;
-+ ret = ioctl(fd, WINESYNC_IOC_SET_EVENT, &event_args);
++ ret = ioctl(fd, NTSYNC_IOC_SET_EVENT, &event_args);
+ EXPECT_EQ(0, ret);
+ EXPECT_EQ(1, event_args.signaled);
+ check_event_state(fd, event_args.event, 1, 0);
@@ -3948,7 +3766,7 @@ index 7e99f09b113b..3a9ac69308af 100644
+ check_event_state(fd, event_args.event, 0, 0);
+
+ event_args.signaled = 0xdeadbeef;
-+ ret = ioctl(fd, WINESYNC_IOC_RESET_EVENT, &event_args);
++ ret = ioctl(fd, NTSYNC_IOC_RESET_EVENT, &event_args);
+ EXPECT_EQ(0, ret);
+ EXPECT_EQ(0, event_args.signaled);
+ check_event_state(fd, event_args.event, 0, 0);
@@ -3957,21 +3775,21 @@ index 7e99f09b113b..3a9ac69308af 100644
+ EXPECT_EQ(-1, ret);
+ EXPECT_EQ(ETIMEDOUT, errno);
+
-+ ret = ioctl(fd, WINESYNC_IOC_SET_EVENT, &event_args);
++ ret = ioctl(fd, NTSYNC_IOC_SET_EVENT, &event_args);
+ EXPECT_EQ(0, ret);
+ EXPECT_EQ(0, event_args.signaled);
+
-+ ret = ioctl(fd, WINESYNC_IOC_PULSE_EVENT, &event_args);
++ ret = ioctl(fd, NTSYNC_IOC_PULSE_EVENT, &event_args);
+ EXPECT_EQ(0, ret);
+ EXPECT_EQ(1, event_args.signaled);
+ check_event_state(fd, event_args.event, 0, 0);
+
-+ ret = ioctl(fd, WINESYNC_IOC_PULSE_EVENT, &event_args);
++ ret = ioctl(fd, NTSYNC_IOC_PULSE_EVENT, &event_args);
+ EXPECT_EQ(0, ret);
+ EXPECT_EQ(0, event_args.signaled);
+ check_event_state(fd, event_args.event, 0, 0);
+
-+ ret = ioctl(fd, WINESYNC_IOC_DELETE, &event_args.event);
++ ret = ioctl(fd, NTSYNC_IOC_DELETE, &event_args.event);
+ EXPECT_EQ(0, ret);
+
+ close(fd);
@@ -3979,31 +3797,31 @@ index 7e99f09b113b..3a9ac69308af 100644
+
TEST(test_wait_any)
{
- struct winesync_mutex_args mutex_args = {0};
+ struct ntsync_mutex_args mutex_args = {0};
--
-2.36.0
+2.43.0
-From 6857a39cd264169494908abf8564ac7161773203 Mon Sep 17 00:00:00 2001
-From: Zebediah Figura <zfigura@codeweavers.com>
+From 011b5115949be3b87e3009ea5e4ede6708cf3ece Mon Sep 17 00:00:00 2001
+From: Elizabeth Figura <zfigura@codeweavers.com>
Date: Wed, 19 Jan 2022 21:00:50 -0600
-Subject: [PATCH 28/34] selftests: winesync: Add some tests for wakeup
- signaling with events.
+Subject: [PATCH 27/32] selftests: ntsync: Add some tests for wakeup signaling
+ with events.
---
- .../selftests/drivers/winesync/winesync.c | 152 +++++++++++++++++-
+ .../testing/selftests/drivers/ntsync/ntsync.c | 152 +++++++++++++++++-
1 file changed, 150 insertions(+), 2 deletions(-)
-diff --git a/tools/testing/selftests/drivers/winesync/winesync.c b/tools/testing/selftests/drivers/winesync/winesync.c
-index 3a9ac69308af..2ccc51510230 100644
---- a/tools/testing/selftests/drivers/winesync/winesync.c
-+++ b/tools/testing/selftests/drivers/winesync/winesync.c
+diff --git a/tools/testing/selftests/drivers/ntsync/ntsync.c b/tools/testing/selftests/drivers/ntsync/ntsync.c
+index c158c15fc03e..8f07577cf156 100644
+--- a/tools/testing/selftests/drivers/ntsync/ntsync.c
++++ b/tools/testing/selftests/drivers/ntsync/ntsync.c
@@ -610,6 +610,7 @@ TEST(test_wait_any)
TEST(test_wait_all)
{
-+ struct winesync_event_args event_args = {0};
- struct winesync_mutex_args mutex_args = {0};
- struct winesync_sem_args sem_args = {0};
++ struct ntsync_event_args event_args = {0};
+ struct ntsync_mutex_args mutex_args = {0};
+ struct ntsync_sem_args sem_args = {0};
__u32 objs[2], owner, index;
@@ -632,6 +633,11 @@ TEST(test_wait_all)
EXPECT_EQ(0, ret);
@@ -4011,7 +3829,7 @@ index 3a9ac69308af..2ccc51510230 100644
+ event_args.manual = true;
+ event_args.signaled = true;
-+ ret = ioctl(fd, WINESYNC_IOC_CREATE_EVENT, &event_args);
++ ret = ioctl(fd, NTSYNC_IOC_CREATE_EVENT, &event_args);
+ EXPECT_EQ(0, ret);
+
objs[0] = sem_args.sem;
@@ -4034,9 +3852,9 @@ index 3a9ac69308af..2ccc51510230 100644
ret = wait_all(fd, 2, objs, 123, &index);
@@ -690,6 +704,8 @@ TEST(test_wait_all)
EXPECT_EQ(0, ret);
- ret = ioctl(fd, WINESYNC_IOC_DELETE, &mutex_args.mutex);
+ ret = ioctl(fd, NTSYNC_IOC_DELETE, &mutex_args.mutex);
EXPECT_EQ(0, ret);
-+ ret = ioctl(fd, WINESYNC_IOC_DELETE, &event_args.event);
++ ret = ioctl(fd, NTSYNC_IOC_DELETE, &event_args.event);
+ EXPECT_EQ(0, ret);
close(fd);
@@ -4045,10 +3863,10 @@ index 3a9ac69308af..2ccc51510230 100644
TEST(wake_any)
{
-+ struct winesync_event_args event_args = {0};
- struct winesync_mutex_args mutex_args = {0};
- struct winesync_wait_args wait_args = {0};
- struct winesync_sem_args sem_args = {0};
++ struct ntsync_event_args event_args = {0};
+ struct ntsync_mutex_args mutex_args = {0};
+ struct ntsync_wait_args wait_args = {0};
+ struct ntsync_sem_args sem_args = {0};
@@ -918,10 +935,103 @@ TEST(wake_any)
EXPECT_EQ(0, thread_args.ret);
EXPECT_EQ(1, wait_args.index);
@@ -4057,7 +3875,7 @@ index 3a9ac69308af..2ccc51510230 100644
+
+ event_args.manual = false;
+ event_args.signaled = false;
-+ ret = ioctl(fd, WINESYNC_IOC_CREATE_EVENT, &event_args);
++ ret = ioctl(fd, NTSYNC_IOC_CREATE_EVENT, &event_args);
+ EXPECT_EQ(0, ret);
+
+ objs[1] = event_args.event;
@@ -4068,7 +3886,7 @@ index 3a9ac69308af..2ccc51510230 100644
+ ret = wait_for_thread(thread, 100);
+ EXPECT_EQ(ETIMEDOUT, ret);
+
-+ ret = ioctl(fd, WINESYNC_IOC_SET_EVENT, &event_args);
++ ret = ioctl(fd, NTSYNC_IOC_SET_EVENT, &event_args);
+ EXPECT_EQ(0, ret);
+ EXPECT_EQ(0, event_args.signaled);
+ check_event_state(fd, event_args.event, 0, 0);
@@ -4085,7 +3903,7 @@ index 3a9ac69308af..2ccc51510230 100644
+ ret = wait_for_thread(thread, 100);
+ EXPECT_EQ(ETIMEDOUT, ret);
+
-+ ret = ioctl(fd, WINESYNC_IOC_PULSE_EVENT, &event_args);
++ ret = ioctl(fd, NTSYNC_IOC_PULSE_EVENT, &event_args);
+ EXPECT_EQ(0, ret);
+ EXPECT_EQ(0, event_args.signaled);
+ check_event_state(fd, event_args.event, 0, 0);
@@ -4095,12 +3913,12 @@ index 3a9ac69308af..2ccc51510230 100644
+ EXPECT_EQ(0, thread_args.ret);
+ EXPECT_EQ(1, wait_args.index);
+
-+ ret = ioctl(fd, WINESYNC_IOC_DELETE, &event_args.event);
++ ret = ioctl(fd, NTSYNC_IOC_DELETE, &event_args.event);
+ EXPECT_EQ(0, ret);
+
+ event_args.manual = true;
+ event_args.signaled = false;
-+ ret = ioctl(fd, WINESYNC_IOC_CREATE_EVENT, &event_args);
++ ret = ioctl(fd, NTSYNC_IOC_CREATE_EVENT, &event_args);
+ EXPECT_EQ(0, ret);
+
+ objs[1] = event_args.event;
@@ -4111,7 +3929,7 @@ index 3a9ac69308af..2ccc51510230 100644
+ ret = wait_for_thread(thread, 100);
+ EXPECT_EQ(ETIMEDOUT, ret);
+
-+ ret = ioctl(fd, WINESYNC_IOC_SET_EVENT, &event_args);
++ ret = ioctl(fd, NTSYNC_IOC_SET_EVENT, &event_args);
+ EXPECT_EQ(0, ret);
+ EXPECT_EQ(0, event_args.signaled);
+ check_event_state(fd, event_args.event, 1, 1);
@@ -4121,7 +3939,7 @@ index 3a9ac69308af..2ccc51510230 100644
+ EXPECT_EQ(0, thread_args.ret);
+ EXPECT_EQ(1, wait_args.index);
+
-+ ret = ioctl(fd, WINESYNC_IOC_RESET_EVENT, &event_args);
++ ret = ioctl(fd, NTSYNC_IOC_RESET_EVENT, &event_args);
+ EXPECT_EQ(0, ret);
+ EXPECT_EQ(1, event_args.signaled);
+
@@ -4132,7 +3950,7 @@ index 3a9ac69308af..2ccc51510230 100644
+ ret = wait_for_thread(thread, 100);
+ EXPECT_EQ(ETIMEDOUT, ret);
+
-+ ret = ioctl(fd, WINESYNC_IOC_PULSE_EVENT, &event_args);
++ ret = ioctl(fd, NTSYNC_IOC_PULSE_EVENT, &event_args);
+ EXPECT_EQ(0, ret);
+ EXPECT_EQ(0, event_args.signaled);
+ check_event_state(fd, event_args.event, 0, 1);
@@ -4142,7 +3960,7 @@ index 3a9ac69308af..2ccc51510230 100644
+ EXPECT_EQ(0, thread_args.ret);
+ EXPECT_EQ(1, wait_args.index);
+
-+ ret = ioctl(fd, WINESYNC_IOC_DELETE, &event_args.event);
++ ret = ioctl(fd, NTSYNC_IOC_DELETE, &event_args.event);
+ EXPECT_EQ(0, ret);
+
/* delete an object while it's being waited on */
@@ -4157,11 +3975,11 @@ index 3a9ac69308af..2ccc51510230 100644
TEST(wake_all)
{
-+ struct winesync_event_args manual_event_args = {0};
-+ struct winesync_event_args auto_event_args = {0};
- struct winesync_mutex_args mutex_args = {0};
- struct winesync_wait_args wait_args = {0};
- struct winesync_sem_args sem_args = {0};
++ struct ntsync_event_args manual_event_args = {0};
++ struct ntsync_event_args auto_event_args = {0};
+ struct ntsync_mutex_args mutex_args = {0};
+ struct ntsync_wait_args wait_args = {0};
+ struct ntsync_sem_args sem_args = {0};
struct wait_args thread_args;
- __u32 objs[2], count, index;
+ __u32 objs[4], count, index;
@@ -4174,12 +3992,12 @@ index 3a9ac69308af..2ccc51510230 100644
+ manual_event_args.manual = true;
+ manual_event_args.signaled = true;
-+ ret = ioctl(fd, WINESYNC_IOC_CREATE_EVENT, &manual_event_args);
++ ret = ioctl(fd, NTSYNC_IOC_CREATE_EVENT, &manual_event_args);
+ EXPECT_EQ(0, ret);
+
+ auto_event_args.manual = false;
+ auto_event_args.signaled = true;
-+ ret = ioctl(fd, WINESYNC_IOC_CREATE_EVENT, &auto_event_args);
++ ret = ioctl(fd, NTSYNC_IOC_CREATE_EVENT, &auto_event_args);
+ EXPECT_EQ(0, ret);
+
objs[0] = sem_args.sem;
@@ -4199,25 +4017,25 @@ index 3a9ac69308af..2ccc51510230 100644
check_mutex_state(fd, mutex_args.mutex, 0, 0);
-+ ret = ioctl(fd, WINESYNC_IOC_RESET_EVENT, &manual_event_args);
++ ret = ioctl(fd, NTSYNC_IOC_RESET_EVENT, &manual_event_args);
+ EXPECT_EQ(0, ret);
+ EXPECT_EQ(1, manual_event_args.signaled);
+
sem_args.count = 2;
- ret = ioctl(fd, WINESYNC_IOC_PUT_SEM, &sem_args);
+ ret = ioctl(fd, NTSYNC_IOC_PUT_SEM, &sem_args);
EXPECT_EQ(0, ret);
EXPECT_EQ(0, sem_args.count);
+ check_sem_state(fd, sem_args.sem, 2, 3);
+
-+ ret = ioctl(fd, WINESYNC_IOC_RESET_EVENT, &auto_event_args);
++ ret = ioctl(fd, NTSYNC_IOC_RESET_EVENT, &auto_event_args);
+ EXPECT_EQ(0, ret);
+ EXPECT_EQ(1, auto_event_args.signaled);
+
-+ ret = ioctl(fd, WINESYNC_IOC_SET_EVENT, &manual_event_args);
++ ret = ioctl(fd, NTSYNC_IOC_SET_EVENT, &manual_event_args);
+ EXPECT_EQ(0, ret);
+ EXPECT_EQ(0, manual_event_args.signaled);
+
-+ ret = ioctl(fd, WINESYNC_IOC_SET_EVENT, &auto_event_args);
++ ret = ioctl(fd, NTSYNC_IOC_SET_EVENT, &auto_event_args);
+ EXPECT_EQ(0, ret);
+ EXPECT_EQ(0, auto_event_args.signaled);
+
@@ -4230,81 +4048,81 @@ index 3a9ac69308af..2ccc51510230 100644
EXPECT_EQ(0, ret);
@@ -1034,6 +1178,10 @@ TEST(wake_all)
EXPECT_EQ(0, ret);
- ret = ioctl(fd, WINESYNC_IOC_DELETE, &mutex_args.mutex);
+ ret = ioctl(fd, NTSYNC_IOC_DELETE, &mutex_args.mutex);
EXPECT_EQ(0, ret);
-+ ret = ioctl(fd, WINESYNC_IOC_DELETE, &manual_event_args.event);
++ ret = ioctl(fd, NTSYNC_IOC_DELETE, &manual_event_args.event);
+ EXPECT_EQ(0, ret);
-+ ret = ioctl(fd, WINESYNC_IOC_DELETE, &auto_event_args.event);
++ ret = ioctl(fd, NTSYNC_IOC_DELETE, &auto_event_args.event);
+ EXPECT_EQ(0, ret);
ret = wait_for_thread(thread, 200);
EXPECT_EQ(0, ret);
--
-2.36.0
+2.43.0
-From 8d2d3a310b90252903cc10e84e2bb1a06d7e8fac Mon Sep 17 00:00:00 2001
-From: Zebediah Figura <zfigura@codeweavers.com>
+From 74c862089a6975afeb0a11bfb6e1c632ae231419 Mon Sep 17 00:00:00 2001
+From: Elizabeth Figura <zfigura@codeweavers.com>
Date: Wed, 19 Jan 2022 21:06:22 -0600
-Subject: [PATCH 29/34] selftests: winesync: Add some tests for invalid object
+Subject: [PATCH 28/32] selftests: ntsync: Add some tests for invalid object
handling with events.
---
- .../selftests/drivers/winesync/winesync.c | 34 +++++++++++++++++++
+ .../testing/selftests/drivers/ntsync/ntsync.c | 34 +++++++++++++++++++
1 file changed, 34 insertions(+)
-diff --git a/tools/testing/selftests/drivers/winesync/winesync.c b/tools/testing/selftests/drivers/winesync/winesync.c
-index 2ccc51510230..f2e18836c733 100644
---- a/tools/testing/selftests/drivers/winesync/winesync.c
-+++ b/tools/testing/selftests/drivers/winesync/winesync.c
+diff --git a/tools/testing/selftests/drivers/ntsync/ntsync.c b/tools/testing/selftests/drivers/ntsync/ntsync.c
+index 8f07577cf156..01bd034d4467 100644
+--- a/tools/testing/selftests/drivers/ntsync/ntsync.c
++++ b/tools/testing/selftests/drivers/ntsync/ntsync.c
@@ -712,6 +712,7 @@ TEST(test_wait_all)
TEST(invalid_objects)
{
-+ struct winesync_event_args event_args = {0};
- struct winesync_mutex_args mutex_args = {0};
- struct winesync_wait_args wait_args = {0};
- struct winesync_sem_args sem_args = {0};
++ struct ntsync_event_args event_args = {0};
+ struct ntsync_mutex_args mutex_args = {0};
+ struct ntsync_wait_args wait_args = {0};
+ struct ntsync_sem_args sem_args = {0};
@@ -737,6 +738,22 @@ TEST(invalid_objects)
EXPECT_EQ(-1, ret);
EXPECT_EQ(EINVAL, errno);
-+ ret = ioctl(fd, WINESYNC_IOC_SET_EVENT, &event_args);
++ ret = ioctl(fd, NTSYNC_IOC_SET_EVENT, &event_args);
+ EXPECT_EQ(-1, ret);
+ EXPECT_EQ(EINVAL, errno);
+
-+ ret = ioctl(fd, WINESYNC_IOC_RESET_EVENT, &event_args);
++ ret = ioctl(fd, NTSYNC_IOC_RESET_EVENT, &event_args);
+ EXPECT_EQ(-1, ret);
+ EXPECT_EQ(EINVAL, errno);
+
-+ ret = ioctl(fd, WINESYNC_IOC_PULSE_EVENT, &event_args);
++ ret = ioctl(fd, NTSYNC_IOC_PULSE_EVENT, &event_args);
+ EXPECT_EQ(-1, ret);
+ EXPECT_EQ(EINVAL, errno);
+
-+ ret = ioctl(fd, WINESYNC_IOC_READ_EVENT, &event_args);
++ ret = ioctl(fd, NTSYNC_IOC_READ_EVENT, &event_args);
+ EXPECT_EQ(-1, ret);
+ EXPECT_EQ(EINVAL, errno);
+
wait_args.objs = (uintptr_t)objs;
wait_args.count = 1;
- ret = ioctl(fd, WINESYNC_IOC_WAIT_ANY, &wait_args);
+ ret = ioctl(fd, NTSYNC_IOC_WAIT_ANY, &wait_args);
@@ -763,6 +780,23 @@ TEST(invalid_objects)
EXPECT_EQ(-1, ret);
EXPECT_EQ(EINVAL, errno);
+ event_args.event = sem_args.sem;
-+ ret = ioctl(fd, WINESYNC_IOC_SET_EVENT, &event_args);
++ ret = ioctl(fd, NTSYNC_IOC_SET_EVENT, &event_args);
+ EXPECT_EQ(-1, ret);
+ EXPECT_EQ(EINVAL, errno);
+
-+ ret = ioctl(fd, WINESYNC_IOC_RESET_EVENT, &event_args);
++ ret = ioctl(fd, NTSYNC_IOC_RESET_EVENT, &event_args);
+ EXPECT_EQ(-1, ret);
+ EXPECT_EQ(EINVAL, errno);
+
-+ ret = ioctl(fd, WINESYNC_IOC_PULSE_EVENT, &event_args);
++ ret = ioctl(fd, NTSYNC_IOC_PULSE_EVENT, &event_args);
+ EXPECT_EQ(-1, ret);
+ EXPECT_EQ(EINVAL, errno);
+
-+ ret = ioctl(fd, WINESYNC_IOC_READ_EVENT, &event_args);
++ ret = ioctl(fd, NTSYNC_IOC_READ_EVENT, &event_args);
+ EXPECT_EQ(-1, ret);
+ EXPECT_EQ(EINVAL, errno);
+
@@ -4312,374 +4130,21 @@ index 2ccc51510230..f2e18836c733 100644
objs[1] = sem_args.sem + 1;
wait_args.count = 2;
--
-2.36.0
-
-From 25270ec5877bcf2aa81fc4dd8326a4ee5af6e541 Mon Sep 17 00:00:00 2001
-From: Zebediah Figura <zfigura@codeweavers.com>
-Date: Wed, 19 Jan 2022 22:01:46 -0600
-Subject: [PATCH 30/34] docs: winesync: Document event APIs.
-
----
- Documentation/userspace-api/winesync.rst | 104 ++++++++++++++++++++++-
- 1 file changed, 101 insertions(+), 3 deletions(-)
-
-diff --git a/Documentation/userspace-api/winesync.rst b/Documentation/userspace-api/winesync.rst
-index 34e54be229cf..ffa2f8fbc7e3 100644
---- a/Documentation/userspace-api/winesync.rst
-+++ b/Documentation/userspace-api/winesync.rst
-@@ -18,8 +18,8 @@ interfaces such as futex(2) and poll(2).
- Synchronization primitives
- ==========================
-
--The winesync driver exposes two types of synchronization primitives,
--semaphores and mutexes.
-+The winesync driver exposes three types of synchronization primitives:
-+semaphores, mutexes, and events.
-
- A semaphore holds a single volatile 32-bit counter, and a static
- 32-bit integer denoting the maximum value. It is considered signaled
-@@ -45,6 +45,12 @@ intended use is to store a thread identifier; however, the winesync
- driver does not actually validate that a calling thread provides
- consistent or unique identifiers.
-
-+An event holds a volatile boolean state denoting whether it is
-+signaled or not. There are two types of events, auto-reset and
-+manual-reset. An auto-reset event is designaled when a wait is
-+satisfied; a manual-reset event is not. The event type is specified
-+when the event is created.
-+
- Unless specified otherwise, all operations on an object are atomic and
- totally ordered with respect to other operations on the same object.
-
-@@ -78,6 +84,12 @@ structures used in ioctl calls::
- __u32 count;
- };
-
-+ struct winesync_event_args {
-+ __u32 event;
-+ __u32 signaled;
-+ __u32 manual;
-+ };
-+
- struct winesync_wait_args {
- __u64 timeout;
- __u64 objs;
-@@ -125,6 +137,22 @@ The ioctls are as follows:
- If ``owner`` is nonzero and ``count`` is zero, or if ``owner`` is
- zero and ``count`` is nonzero, the function fails with ``EINVAL``.
-
-+.. c:macro:: WINESYNC_IOC_CREATE_EVENT
-+
-+ Create an event object. Takes a pointer to struct
-+ :c:type:`winesync_event_args`, which is used as follows:
-+
-+ .. list-table::
-+
-+ * - ``event``
-+ - On output, contains the identifier of the created event.
-+ * - ``signaled``
-+ - If nonzero, the event is initially signaled, otherwise
-+ nonsignaled.
-+ * - ``manual``
-+ - If nonzero, the event is a manual-reset event, otherwise
-+ auto-reset.
-+
- .. c:macro:: WINESYNC_IOC_DELETE
-
- Delete an object of any type. Takes an input-only pointer to a
-@@ -178,6 +206,60 @@ The ioctls are as follows:
- unowned and signaled, and eligible threads waiting on it will be
- woken as appropriate.
-
-+.. c:macro:: WINESYNC_IOC_SET_EVENT
-+
-+ Signal an event object. Takes a pointer to struct
-+ :c:type:`winesync_event_args`, which is used as follows:
-+
-+ .. list-table::
-+
-+ * - ``event``
-+ - Event object to set.
-+ * - ``signaled``
-+ - On output, contains the previous state of the event.
-+ * - ``manual``
-+ - Unused.
-+
-+ Eligible threads will be woken, and auto-reset events will be
-+ designaled appropriately.
-+
-+.. c:macro:: WINESYNC_IOC_RESET_EVENT
-+
-+ Designal an event object. Takes a pointer to struct
-+ :c:type:`winesync_event_args`, which is used as follows:
-+
-+ .. list-table::
-+
-+ * - ``event``
-+ - Event object to reset.
-+ * - ``signaled``
-+ - On output, contains the previous state of the event.
-+ * - ``manual``
-+ - Unused.
-+
-+.. c:macro:: WINESYNC_IOC_PULSE_EVENT
-+
-+ Wake threads waiting on an event object without leaving it in a
-+ signaled state. Takes a pointer to struct
-+ :c:type:`winesync_event_args`, which is used as follows:
-+
-+ .. list-table::
-+
-+ * - ``event``
-+ - Event object to pulse.
-+ * - ``signaled``
-+ - On output, contains the previous state of the event.
-+ * - ``manual``
-+ - Unused.
-+
-+ A pulse operation can be thought of as a set followed by a reset,
-+ performed as a single atomic operation. If two threads are waiting
-+ on an auto-reset event which is pulsed, only one will be woken. If
-+ two threads are waiting a manual-reset event which is pulsed, both
-+ will be woken. However, in both cases, the event will be unsignaled
-+ afterwards, and a simultaneous read operation will always report the
-+ event as unsignaled.
-+
- .. c:macro:: WINESYNC_IOC_READ_SEM
-
- Read the current state of a semaphore object. Takes a pointer to
-@@ -211,6 +293,21 @@ The ioctls are as follows:
- ``EOWNERDEAD``. In this case, ``count`` and ``owner`` are set to
- zero.
-
-+.. c:macro:: WINESYNC_IOC_READ_EVENT
-+
-+ Read the current state of an event object. Takes a pointer to struct
-+ :c:type:`winesync_event_args`, which is used as follows:
-+
-+ .. list-table::
-+
-+ * - ``event``
-+ - Event object.
-+ * - ``signaled``
-+ - On output, contains the current state of the event.
-+ * - ``manual``
-+ - On output, contains 1 if the event is a manual-reset event,
-+ and 0 otherwise.
-+
- .. c:macro:: WINESYNC_IOC_KILL_OWNER
-
- Mark any mutexes owned by the given owner as unowned and
-@@ -272,7 +369,8 @@ The ioctls are as follows:
- considered to be signaled if it is unowned or if its owner matches
- the ``owner`` argument, and is acquired by incrementing its
- recursion count by one and setting its owner to the ``owner``
-- argument.
-+ argument. An auto-reset event is acquired by designaling it; a
-+ manual-reset event is not affected by acquisition.
-
- Acquisition is atomic and totally ordered with respect to other
- operations on the same object. If two wait operations (with
---
-2.36.0
-
-From 80f5b4dfd947592ff89cb54a07ce9d1087c608d0 Mon Sep 17 00:00:00 2001
-From: Zebediah Figura <zfigura@codeweavers.com>
-Date: Wed, 13 Apr 2022 20:02:39 -0500
-Subject: [PATCH 31/34] winesync: Introduce alertable waits.
-
----
- drivers/misc/winesync.c | 68 ++++++++++++++++++++++++++++++-----
- include/uapi/linux/winesync.h | 2 +-
- 2 files changed, 60 insertions(+), 10 deletions(-)
-
-diff --git a/drivers/misc/winesync.c b/drivers/misc/winesync.c
-index 4fbf231a7909..7a28f58dbbf2 100644
---- a/drivers/misc/winesync.c
-+++ b/drivers/misc/winesync.c
-@@ -841,10 +841,11 @@ static int setup_wait(struct winesync_device *dev,
- const __u32 count = args->count;
- struct winesync_q *q;
- ktime_t timeout = 0;
-+ __u32 total_count;
- __u32 *ids;
- __u32 i, j;
-
-- if (!args->owner || args->pad)
-+ if (!args->owner)
- return -EINVAL;
-
- if (args->timeout) {
-@@ -858,7 +859,11 @@ static int setup_wait(struct winesync_device *dev,
- timeout = timespec64_to_ns(&to);
- }
-
-- ids = kmalloc_array(count, sizeof(*ids), GFP_KERNEL);
-+ total_count = count;
-+ if (args->alert)
-+ total_count++;
-+
-+ ids = kmalloc_array(total_count, sizeof(*ids), GFP_KERNEL);
- if (!ids)
- return -ENOMEM;
- if (copy_from_user(ids, u64_to_user_ptr(args->objs),
-@@ -866,8 +871,10 @@ static int setup_wait(struct winesync_device *dev,
- kfree(ids);
- return -EFAULT;
- }
-+ if (args->alert)
-+ ids[count] = args->alert;
-
-- q = kmalloc(struct_size(q, entries, count), GFP_KERNEL);
-+ q = kmalloc(struct_size(q, entries, total_count), GFP_KERNEL);
- if (!q) {
- kfree(ids);
- return -ENOMEM;
-@@ -879,7 +886,7 @@ static int setup_wait(struct winesync_device *dev,
- q->ownerdead = false;
- q->count = count;
-
-- for (i = 0; i < count; i++) {
-+ for (i = 0; i < total_count; i++) {
- struct winesync_q_entry *entry = &q->entries[i];
- struct winesync_obj *obj = get_obj(dev, ids[i]);
-
-@@ -934,9 +941,9 @@ static int winesync_wait_any(struct winesync_device *dev, void __user *argp)
- {
- struct winesync_wait_args args;
- struct winesync_q *q;
-+ __u32 i, total_count;
- ktime_t timeout;
- int signaled;
-- __u32 i;
- int ret;
-
- if (copy_from_user(&args, argp, sizeof(args)))
-@@ -946,9 +953,13 @@ static int winesync_wait_any(struct winesync_device *dev, void __user *argp)
- if (ret < 0)
- return ret;
-
-+ total_count = args.count;
-+ if (args.alert)
-+ total_count++;
-+
- /* queue ourselves */
-
-- for (i = 0; i < args.count; i++) {
-+ for (i = 0; i < total_count; i++) {
- struct winesync_q_entry *entry = &q->entries[i];
- struct winesync_obj *obj = entry->obj;
-
-@@ -957,9 +968,15 @@ static int winesync_wait_any(struct winesync_device *dev, void __user *argp)
- spin_unlock(&obj->lock);
- }
-
-- /* check if we are already signaled */
-+ /*
-+ * Check if we are already signaled.
-+ *
-+ * Note that the API requires that normal objects are checked before
-+ * the alert event. Hence we queue the alert event last, and check
-+ * objects in order.
-+ */
-
-- for (i = 0; i < args.count; i++) {
-+ for (i = 0; i < total_count; i++) {
- struct winesync_obj *obj = q->entries[i].obj;
-
- if (atomic_read(&q->signaled) != -1)
-@@ -976,7 +993,7 @@ static int winesync_wait_any(struct winesync_device *dev, void __user *argp)
-
- /* and finally, unqueue */
-
-- for (i = 0; i < args.count; i++) {
-+ for (i = 0; i < total_count; i++) {
- struct winesync_q_entry *entry = &q->entries[i];
- struct winesync_obj *obj = entry->obj;
-
-@@ -1036,6 +1053,14 @@ static int winesync_wait_all(struct winesync_device *dev, void __user *argp)
- */
- list_add_tail(&entry->node, &obj->all_waiters);
- }
-+ if (args.alert) {
-+ struct winesync_q_entry *entry = &q->entries[args.count];
-+ struct winesync_obj *obj = entry->obj;
-+
-+ spin_lock(&obj->lock);
-+ list_add_tail(&entry->node, &obj->any_waiters);
-+ spin_unlock(&obj->lock);
-+ }
-
- /* check if we are already signaled */
-
-@@ -1043,6 +1068,21 @@ static int winesync_wait_all(struct winesync_device *dev, void __user *argp)
-
- spin_unlock(&dev->wait_all_lock);
-
-+ /*
-+ * Check if the alert event is signaled, making sure to do so only
-+ * after checking if the other objects are signaled.
-+ */
-+
-+ if (args.alert) {
-+ struct winesync_obj *obj = q->entries[args.count].obj;
-+
-+ if (atomic_read(&q->signaled) == -1) {
-+ spin_lock(&obj->lock);
-+ try_wake_any_obj(obj);
-+ spin_unlock(&obj->lock);
-+ }
-+ }
-+
- /* sleep */
-
- ret = winesync_schedule(q, args.timeout ? &timeout : NULL);
-@@ -1065,6 +1105,16 @@ static int winesync_wait_all(struct winesync_device *dev, void __user *argp)
-
- put_obj(obj);
- }
-+ if (args.alert) {
-+ struct winesync_q_entry *entry = &q->entries[args.count];
-+ struct winesync_obj *obj = entry->obj;
-+
-+ spin_lock(&obj->lock);
-+ list_del(&entry->node);
-+ spin_unlock(&obj->lock);
-+
-+ put_obj(obj);
-+ }
-
- spin_unlock(&dev->wait_all_lock);
-
-diff --git a/include/uapi/linux/winesync.h b/include/uapi/linux/winesync.h
-index fb3788339ffe..5b4e369f7469 100644
---- a/include/uapi/linux/winesync.h
-+++ b/include/uapi/linux/winesync.h
-@@ -34,7 +34,7 @@ struct winesync_wait_args {
- __u32 count;
- __u32 owner;
- __u32 index;
-- __u32 pad;
-+ __u32 alert;
- };
-
- #define WINESYNC_IOC_BASE 0xf7
---
-2.37.3
+2.43.0
-From 127efad71a0702a68890097b114b3467c234259f Mon Sep 17 00:00:00 2001
-From: Zebediah Figura <zfigura@codeweavers.com>
+From 8550d7aec916d737b2e81f5916c25da69d0d3de0 Mon Sep 17 00:00:00 2001
+From: Elizabeth Figura <zfigura@codeweavers.com>
Date: Wed, 20 Apr 2022 18:08:37 -0500
-Subject: [PATCH 32/34] selftests: winesync: Add tests for alertable waits.
+Subject: [PATCH 29/32] selftests: ntsync: Add tests for alertable waits.
---
- .../selftests/drivers/winesync/winesync.c | 191 +++++++++++++++++-
- 1 file changed, 188 insertions(+), 3 deletions(-)
+ .../testing/selftests/drivers/ntsync/ntsync.c | 189 +++++++++++++++++-
+ 1 file changed, 186 insertions(+), 3 deletions(-)
-diff --git a/tools/testing/selftests/drivers/winesync/winesync.c b/tools/testing/selftests/drivers/winesync/winesync.c
-index f2e18836c733..a87e3c48709b 100644
---- a/tools/testing/selftests/drivers/winesync/winesync.c
-+++ b/tools/testing/selftests/drivers/winesync/winesync.c
+diff --git a/tools/testing/selftests/drivers/ntsync/ntsync.c b/tools/testing/selftests/drivers/ntsync/ntsync.c
+index 01bd034d4467..a58387d6744b 100644
+--- a/tools/testing/selftests/drivers/ntsync/ntsync.c
++++ b/tools/testing/selftests/drivers/ntsync/ntsync.c
@@ -110,7 +110,7 @@ static int read_event_state(int fd, __u32 event, __u32 *signaled, __u32 *manual)
})
@@ -4687,7 +4152,7 @@ index f2e18836c733..a87e3c48709b 100644
- const __u32 *objs, __u32 owner, __u32 *index)
+ const __u32 *objs, __u32 owner, __u32 alert, __u32 *index)
{
- struct winesync_wait_args args = {0};
+ struct ntsync_wait_args args = {0};
struct timespec timeout;
@@ -123,6 +123,7 @@ static int wait_objs(int fd, unsigned long request, __u32 count,
args.objs = (uintptr_t)objs;
@@ -4697,56 +4162,54 @@ index f2e18836c733..a87e3c48709b 100644
ret = ioctl(fd, request, &args);
*index = args.index;
return ret;
-@@ -131,13 +132,29 @@ static int wait_objs(int fd, unsigned long request, __u32 count,
+@@ -131,13 +132,27 @@ static int wait_objs(int fd, unsigned long request, __u32 count,
static int wait_any(int fd, __u32 count, const __u32 *objs,
__u32 owner, __u32 *index)
{
-- return wait_objs(fd, WINESYNC_IOC_WAIT_ANY, count, objs, owner, index);
-+ return wait_objs(fd, WINESYNC_IOC_WAIT_ANY,
-+ count, objs, owner, 0, index);
+- return wait_objs(fd, NTSYNC_IOC_WAIT_ANY, count, objs, owner, index);
++ return wait_objs(fd, NTSYNC_IOC_WAIT_ANY, count, objs, owner, 0, index);
}
static int wait_all(int fd, __u32 count, const __u32 *objs,
__u32 owner, __u32 *index)
{
-- return wait_objs(fd, WINESYNC_IOC_WAIT_ALL, count, objs, owner, index);
-+ return wait_objs(fd, WINESYNC_IOC_WAIT_ALL,
-+ count, objs, owner, 0, index);
+- return wait_objs(fd, NTSYNC_IOC_WAIT_ALL, count, objs, owner, index);
++ return wait_objs(fd, NTSYNC_IOC_WAIT_ALL, count, objs, owner, 0, index);
+}
+
+static int wait_any_alert(int fd, __u32 count, const __u32 *objs,
+ __u32 owner, __u32 alert, __u32 *index)
+{
-+ return wait_objs(fd, WINESYNC_IOC_WAIT_ANY,
++ return wait_objs(fd, NTSYNC_IOC_WAIT_ANY,
+ count, objs, owner, alert, index);
+}
+
+static int wait_all_alert(int fd, __u32 count, const __u32 *objs,
+ __u32 owner, __u32 alert, __u32 *index)
+{
-+ return wait_objs(fd, WINESYNC_IOC_WAIT_ALL,
++ return wait_objs(fd, NTSYNC_IOC_WAIT_ALL,
+ count, objs, owner, alert, index);
}
TEST(semaphore_state)
-@@ -1225,4 +1242,172 @@ TEST(wake_all)
+@@ -1225,4 +1240,172 @@ TEST(wake_all)
close(fd);
}
+TEST(alert_any)
+{
-+ struct winesync_event_args event_args = {0};
-+ struct winesync_sem_args sem_args = {0};
++ struct ntsync_event_args event_args = {0};
++ struct ntsync_sem_args sem_args = {0};
+ __u32 objs[2], index;
+ int fd, ret;
+
-+ fd = open("/dev/winesync", O_CLOEXEC | O_RDONLY);
++ fd = open("/dev/ntsync", O_CLOEXEC | O_RDONLY);
+ ASSERT_LE(0, fd);
+
+ sem_args.count = 0;
+ sem_args.max = 2;
+ sem_args.sem = 0xdeadbeef;
-+ ret = ioctl(fd, WINESYNC_IOC_CREATE_SEM, &sem_args);
++ ret = ioctl(fd, NTSYNC_IOC_CREATE_SEM, &sem_args);
+ EXPECT_EQ(0, ret);
+ EXPECT_NE(0xdeadbeef, sem_args.sem);
+ objs[0] = sem_args.sem;
@@ -4754,28 +4217,28 @@ index f2e18836c733..a87e3c48709b 100644
+ sem_args.count = 1;
+ sem_args.max = 2;
+ sem_args.sem = 0xdeadbeef;
-+ ret = ioctl(fd, WINESYNC_IOC_CREATE_SEM, &sem_args);
++ ret = ioctl(fd, NTSYNC_IOC_CREATE_SEM, &sem_args);
+ EXPECT_EQ(0, ret);
+ EXPECT_NE(0xdeadbeef, sem_args.sem);
+ objs[1] = sem_args.sem;
+
+ event_args.manual = true;
+ event_args.signaled = true;
-+ ret = ioctl(fd, WINESYNC_IOC_CREATE_EVENT, &event_args);
++ ret = ioctl(fd, NTSYNC_IOC_CREATE_EVENT, &event_args);
+ EXPECT_EQ(0, ret);
+
+ ret = wait_any_alert(fd, 0, NULL, 123, event_args.event, &index);
+ EXPECT_EQ(0, ret);
+ EXPECT_EQ(0, index);
+
-+ ret = ioctl(fd, WINESYNC_IOC_RESET_EVENT, &event_args);
++ ret = ioctl(fd, NTSYNC_IOC_RESET_EVENT, &event_args);
+ EXPECT_EQ(0, ret);
+
+ ret = wait_any_alert(fd, 0, NULL, 123, event_args.event, &index);
+ EXPECT_EQ(-1, ret);
+ EXPECT_EQ(ETIMEDOUT, errno);
+
-+ ret = ioctl(fd, WINESYNC_IOC_SET_EVENT, &event_args);
++ ret = ioctl(fd, NTSYNC_IOC_SET_EVENT, &event_args);
+ EXPECT_EQ(0, ret);
+
+ ret = wait_any_alert(fd, 2, objs, 123, event_args.event, &index);
@@ -4786,19 +4249,19 @@ index f2e18836c733..a87e3c48709b 100644
+ EXPECT_EQ(0, ret);
+ EXPECT_EQ(2, index);
+
-+ ret = ioctl(fd, WINESYNC_IOC_DELETE, &event_args.event);
++ ret = ioctl(fd, NTSYNC_IOC_DELETE, &event_args.event);
+ EXPECT_EQ(0, ret);
+
+ /* test with an auto-reset event */
+
+ event_args.manual = false;
+ event_args.signaled = true;
-+ ret = ioctl(fd, WINESYNC_IOC_CREATE_EVENT, &event_args);
++ ret = ioctl(fd, NTSYNC_IOC_CREATE_EVENT, &event_args);
+ EXPECT_EQ(0, ret);
+
+ sem_args.sem = objs[0];
+ sem_args.count = 1;
-+ ret = ioctl(fd, WINESYNC_IOC_PUT_SEM, &sem_args);
++ ret = ioctl(fd, NTSYNC_IOC_PUT_SEM, &sem_args);
+ EXPECT_EQ(0, ret);
+
+ ret = wait_any_alert(fd, 2, objs, 123, event_args.event, &index);
@@ -4813,12 +4276,12 @@ index f2e18836c733..a87e3c48709b 100644
+ EXPECT_EQ(-1, ret);
+ EXPECT_EQ(ETIMEDOUT, errno);
+
-+ ret = ioctl(fd, WINESYNC_IOC_DELETE, &event_args.event);
++ ret = ioctl(fd, NTSYNC_IOC_DELETE, &event_args.event);
+ EXPECT_EQ(0, ret);
+
-+ ret = ioctl(fd, WINESYNC_IOC_DELETE, &objs[0]);
++ ret = ioctl(fd, NTSYNC_IOC_DELETE, &objs[0]);
+ EXPECT_EQ(0, ret);
-+ ret = ioctl(fd, WINESYNC_IOC_DELETE, &objs[1]);
++ ret = ioctl(fd, NTSYNC_IOC_DELETE, &objs[1]);
+ EXPECT_EQ(0, ret);
+
+ close(fd);
@@ -4826,18 +4289,18 @@ index f2e18836c733..a87e3c48709b 100644
+
+TEST(alert_all)
+{
-+ struct winesync_event_args event_args = {0};
-+ struct winesync_sem_args sem_args = {0};
++ struct ntsync_event_args event_args = {0};
++ struct ntsync_sem_args sem_args = {0};
+ __u32 objs[2], index;
+ int fd, ret;
+
-+ fd = open("/dev/winesync", O_CLOEXEC | O_RDONLY);
++ fd = open("/dev/ntsync", O_CLOEXEC | O_RDONLY);
+ ASSERT_LE(0, fd);
+
+ sem_args.count = 2;
+ sem_args.max = 2;
+ sem_args.sem = 0xdeadbeef;
-+ ret = ioctl(fd, WINESYNC_IOC_CREATE_SEM, &sem_args);
++ ret = ioctl(fd, NTSYNC_IOC_CREATE_SEM, &sem_args);
+ EXPECT_EQ(0, ret);
+ EXPECT_NE(0xdeadbeef, sem_args.sem);
+ objs[0] = sem_args.sem;
@@ -4845,14 +4308,14 @@ index f2e18836c733..a87e3c48709b 100644
+ sem_args.count = 1;
+ sem_args.max = 2;
+ sem_args.sem = 0xdeadbeef;
-+ ret = ioctl(fd, WINESYNC_IOC_CREATE_SEM, &sem_args);
++ ret = ioctl(fd, NTSYNC_IOC_CREATE_SEM, &sem_args);
+ EXPECT_EQ(0, ret);
+ EXPECT_NE(0xdeadbeef, sem_args.sem);
+ objs[1] = sem_args.sem;
+
+ event_args.manual = true;
+ event_args.signaled = true;
-+ ret = ioctl(fd, WINESYNC_IOC_CREATE_EVENT, &event_args);
++ ret = ioctl(fd, NTSYNC_IOC_CREATE_EVENT, &event_args);
+ EXPECT_EQ(0, ret);
+
+ ret = wait_all_alert(fd, 2, objs, 123, event_args.event, &index);
@@ -4863,19 +4326,19 @@ index f2e18836c733..a87e3c48709b 100644
+ EXPECT_EQ(0, ret);
+ EXPECT_EQ(2, index);
+
-+ ret = ioctl(fd, WINESYNC_IOC_DELETE, &event_args.event);
++ ret = ioctl(fd, NTSYNC_IOC_DELETE, &event_args.event);
+ EXPECT_EQ(0, ret);
+
+ /* test with an auto-reset event */
+
+ event_args.manual = false;
+ event_args.signaled = true;
-+ ret = ioctl(fd, WINESYNC_IOC_CREATE_EVENT, &event_args);
++ ret = ioctl(fd, NTSYNC_IOC_CREATE_EVENT, &event_args);
+ EXPECT_EQ(0, ret);
+
+ sem_args.sem = objs[1];
+ sem_args.count = 2;
-+ ret = ioctl(fd, WINESYNC_IOC_PUT_SEM, &sem_args);
++ ret = ioctl(fd, NTSYNC_IOC_PUT_SEM, &sem_args);
+ EXPECT_EQ(0, ret);
+
+ ret = wait_all_alert(fd, 2, objs, 123, event_args.event, &index);
@@ -4890,12 +4353,12 @@ index f2e18836c733..a87e3c48709b 100644
+ EXPECT_EQ(-1, ret);
+ EXPECT_EQ(ETIMEDOUT, errno);
+
-+ ret = ioctl(fd, WINESYNC_IOC_DELETE, &event_args.event);
++ ret = ioctl(fd, NTSYNC_IOC_DELETE, &event_args.event);
+ EXPECT_EQ(0, ret);
+
-+ ret = ioctl(fd, WINESYNC_IOC_DELETE, &objs[0]);
++ ret = ioctl(fd, NTSYNC_IOC_DELETE, &objs[0]);
+ EXPECT_EQ(0, ret);
-+ ret = ioctl(fd, WINESYNC_IOC_DELETE, &objs[1]);
++ ret = ioctl(fd, NTSYNC_IOC_DELETE, &objs[1]);
+ EXPECT_EQ(0, ret);
+
+ close(fd);
@@ -4903,42 +4366,42 @@ index f2e18836c733..a87e3c48709b 100644
+
TEST_HARNESS_MAIN
--
-2.36.0
+2.43.0
-From e5ec8276fae40b6a2cdab3cb728160705c0f40ab Mon Sep 17 00:00:00 2001
-From: Zebediah Figura <zfigura@codeweavers.com>
+From 96d776b0b301b8a9f0b2fc27e62ff8b26e407072 Mon Sep 17 00:00:00 2001
+From: Elizabeth Figura <zfigura@codeweavers.com>
Date: Wed, 20 Apr 2022 18:24:43 -0500
-Subject: [PATCH 33/34] serftests: winesync: Add some tests for wakeup
- signaling via alerts.
+Subject: [PATCH 30/32] selftests: ntsync: Add some tests for wakeup signaling
+ via alerts.
---
- .../selftests/drivers/winesync/winesync.c | 66 +++++++++++++++++++
+ .../testing/selftests/drivers/ntsync/ntsync.c | 66 +++++++++++++++++++
1 file changed, 66 insertions(+)
-diff --git a/tools/testing/selftests/drivers/winesync/winesync.c b/tools/testing/selftests/drivers/winesync/winesync.c
-index a87e3c48709b..169e922484b0 100644
---- a/tools/testing/selftests/drivers/winesync/winesync.c
-+++ b/tools/testing/selftests/drivers/winesync/winesync.c
-@@ -1245,8 +1245,12 @@ TEST(wake_all)
+diff --git a/tools/testing/selftests/drivers/ntsync/ntsync.c b/tools/testing/selftests/drivers/ntsync/ntsync.c
+index a58387d6744b..fda9f1c5e810 100644
+--- a/tools/testing/selftests/drivers/ntsync/ntsync.c
++++ b/tools/testing/selftests/drivers/ntsync/ntsync.c
+@@ -1243,8 +1243,12 @@ TEST(wake_all)
TEST(alert_any)
{
- struct winesync_event_args event_args = {0};
-+ struct winesync_wait_args wait_args = {0};
- struct winesync_sem_args sem_args = {0};
+ struct ntsync_event_args event_args = {0};
++ struct ntsync_wait_args wait_args = {0};
+ struct ntsync_sem_args sem_args = {0};
+ struct wait_args thread_args;
+ struct timespec timeout;
__u32 objs[2], index;
+ pthread_t thread;
int fd, ret;
- fd = open("/dev/winesync", O_CLOEXEC | O_RDONLY);
-@@ -1295,6 +1299,35 @@ TEST(alert_any)
+ fd = open("/dev/ntsync", O_CLOEXEC | O_RDONLY);
+@@ -1293,6 +1297,35 @@ TEST(alert_any)
EXPECT_EQ(0, ret);
EXPECT_EQ(2, index);
+ /* test wakeup via alert */
+
-+ ret = ioctl(fd, WINESYNC_IOC_RESET_EVENT, &event_args);
++ ret = ioctl(fd, NTSYNC_IOC_RESET_EVENT, &event_args);
+ EXPECT_EQ(0, ret);
+
+ get_abs_timeout(&timeout, CLOCK_MONOTONIC, 1000);
@@ -4950,14 +4413,14 @@ index a87e3c48709b..169e922484b0 100644
+ wait_args.alert = event_args.event;
+ thread_args.fd = fd;
+ thread_args.args = &wait_args;
-+ thread_args.request = WINESYNC_IOC_WAIT_ANY;
++ thread_args.request = NTSYNC_IOC_WAIT_ANY;
+ ret = pthread_create(&thread, NULL, wait_thread, &thread_args);
+ EXPECT_EQ(0, ret);
+
+ ret = wait_for_thread(thread, 100);
+ EXPECT_EQ(ETIMEDOUT, ret);
+
-+ ret = ioctl(fd, WINESYNC_IOC_SET_EVENT, &event_args);
++ ret = ioctl(fd, NTSYNC_IOC_SET_EVENT, &event_args);
+ EXPECT_EQ(0, ret);
+
+ ret = wait_for_thread(thread, 100);
@@ -4965,29 +4428,29 @@ index a87e3c48709b..169e922484b0 100644
+ EXPECT_EQ(0, thread_args.ret);
+ EXPECT_EQ(2, wait_args.index);
+
- ret = ioctl(fd, WINESYNC_IOC_DELETE, &event_args.event);
+ ret = ioctl(fd, NTSYNC_IOC_DELETE, &event_args.event);
EXPECT_EQ(0, ret);
-@@ -1336,8 +1369,12 @@ TEST(alert_any)
+@@ -1334,8 +1367,12 @@ TEST(alert_any)
TEST(alert_all)
{
- struct winesync_event_args event_args = {0};
-+ struct winesync_wait_args wait_args = {0};
- struct winesync_sem_args sem_args = {0};
+ struct ntsync_event_args event_args = {0};
++ struct ntsync_wait_args wait_args = {0};
+ struct ntsync_sem_args sem_args = {0};
+ struct wait_args thread_args;
+ struct timespec timeout;
__u32 objs[2], index;
+ pthread_t thread;
int fd, ret;
- fd = open("/dev/winesync", O_CLOEXEC | O_RDONLY);
-@@ -1372,6 +1409,35 @@ TEST(alert_all)
+ fd = open("/dev/ntsync", O_CLOEXEC | O_RDONLY);
+@@ -1370,6 +1407,35 @@ TEST(alert_all)
EXPECT_EQ(0, ret);
EXPECT_EQ(2, index);
+ /* test wakeup via alert */
+
-+ ret = ioctl(fd, WINESYNC_IOC_RESET_EVENT, &event_args);
++ ret = ioctl(fd, NTSYNC_IOC_RESET_EVENT, &event_args);
+ EXPECT_EQ(0, ret);
+
+ get_abs_timeout(&timeout, CLOCK_MONOTONIC, 1000);
@@ -4999,14 +4462,14 @@ index a87e3c48709b..169e922484b0 100644
+ wait_args.alert = event_args.event;
+ thread_args.fd = fd;
+ thread_args.args = &wait_args;
-+ thread_args.request = WINESYNC_IOC_WAIT_ALL;
++ thread_args.request = NTSYNC_IOC_WAIT_ALL;
+ ret = pthread_create(&thread, NULL, wait_thread, &thread_args);
+ EXPECT_EQ(0, ret);
+
+ ret = wait_for_thread(thread, 100);
+ EXPECT_EQ(ETIMEDOUT, ret);
+
-+ ret = ioctl(fd, WINESYNC_IOC_SET_EVENT, &event_args);
++ ret = ioctl(fd, NTSYNC_IOC_SET_EVENT, &event_args);
+ EXPECT_EQ(0, ret);
+
+ ret = wait_for_thread(thread, 100);
@@ -5014,32 +4477,431 @@ index a87e3c48709b..169e922484b0 100644
+ EXPECT_EQ(0, thread_args.ret);
+ EXPECT_EQ(2, wait_args.index);
+
- ret = ioctl(fd, WINESYNC_IOC_DELETE, &event_args.event);
+ ret = ioctl(fd, NTSYNC_IOC_DELETE, &event_args.event);
EXPECT_EQ(0, ret);
--
-2.36.0
+2.43.0
+
+From 5ecf8efc0d4f019edcf4334b54314226bc30bd62 Mon Sep 17 00:00:00 2001
+From: Elizabeth Figura <zfigura@codeweavers.com>
+Date: Fri, 5 Mar 2021 12:22:55 -0600
+Subject: [PATCH 31/32] maintainers: Add an entry for ntsync.
+
+---
+ MAINTAINERS | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/MAINTAINERS b/MAINTAINERS
+index a7c4cf8201e0..90e84b768c42 100644
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -15341,6 +15341,15 @@ T: git https://github.com/Paragon-Software-Group/linux-ntfs3.git
+ F: Documentation/filesystems/ntfs3.rst
+ F: fs/ntfs3/
+
++NTSYNC SYNCHRONIZATION PRIMITIVE DRIVER
++M: Elizabeth Figura <zfigura@codeweavers.com>
++L: wine-devel@winehq.org
++S: Supported
++F: Documentation/userspace-api/ntsync.rst
++F: drivers/misc/ntsync.c
++F: include/uapi/linux/ntsync.h
++F: tools/testing/selftests/drivers/ntsync/
++
+ NUBUS SUBSYSTEM
+ M: Finn Thain <fthain@linux-m68k.org>
+ L: linux-m68k@lists.linux-m68k.org
+--
+2.43.0
-From 50ed00eef095c7799949b2523a5c21210b374f86 Mon Sep 17 00:00:00 2001
-From: Zebediah Figura <zfigura@codeweavers.com>
-Date: Wed, 20 Apr 2022 18:58:17 -0500
-Subject: [PATCH 34/34] docs: winesync: Document alertable waits.
+From e4db1ebaa7b9b150bcf54a4d57699e746b4d5b75 Mon Sep 17 00:00:00 2001
+From: Peter Jung <admin@ptr1337.dev>
+Date: Wed, 24 Jan 2024 17:37:06 +0100
+Subject: [PATCH 32/32] docs: ntsync: Add documentation for the ntsync uAPI.
+Signed-off-by: Peter Jung <admin@ptr1337.dev>
---
- Documentation/userspace-api/winesync.rst | 40 ++++++++++++++++++------
- 1 file changed, 31 insertions(+), 9 deletions(-)
+ Documentation/userspace-api/index.rst | 1 +
+ Documentation/userspace-api/ntsync.rst | 445 +++++++++++++++++++++++++
+ 2 files changed, 446 insertions(+)
+ create mode 100644 Documentation/userspace-api/ntsync.rst
-diff --git a/Documentation/userspace-api/winesync.rst b/Documentation/userspace-api/winesync.rst
-index ffa2f8fbc7e3..f0110d2744c7 100644
---- a/Documentation/userspace-api/winesync.rst
-+++ b/Documentation/userspace-api/winesync.rst
-@@ -354,9 +354,13 @@ The ioctls are as follows:
- ``EINVAL``.
- * - ``index``
- - On success, contains the index (into ``objs``) of the object
-- which was signaled.
-- * - ``pad``
-- - This field is not used and must be set to zero.
+diff --git a/Documentation/userspace-api/index.rst b/Documentation/userspace-api/index.rst
+index 031df47a7c19..188bf15c4ecf 100644
+--- a/Documentation/userspace-api/index.rst
++++ b/Documentation/userspace-api/index.rst
+@@ -33,6 +33,7 @@ place where this information is gathered.
+ sysfs-platform_profile
+ vduse
+ futex2
++ ntsync
+
+ .. only:: subproject and html
+
+diff --git a/Documentation/userspace-api/ntsync.rst b/Documentation/userspace-api/ntsync.rst
+new file mode 100644
+index 000000000000..45d945b3e246
+--- /dev/null
++++ b/Documentation/userspace-api/ntsync.rst
+@@ -0,0 +1,445 @@
++===================================
++NT synchronization primitive driver
++===================================
++
++This page documents the user-space API for the ntsync driver.
++
++ntsync is a support driver for emulation of NT synchronization
++primitives by user-space NT emulators. It exists because implementation
++in user-space, using existing tools, cannot match Windows performance
++while offering accurate semantics. It is implemented entirely in
++software, and does not drive any hardware device.
++
++This interface is meant as a compatibility tool only, and should not
++be used for general synchronization. Instead use generic, versatile
++interfaces such as futex(2) and poll(2).
++
++Synchronization primitives
++==========================
++
++The ntsync driver exposes three types of synchronization primitives:
++semaphores, mutexes, and events.
++
++A semaphore holds a single volatile 32-bit counter, and a static
++32-bit integer denoting the maximum value. It is considered signaled
++when the counter is nonzero. The counter is decremented by one when a
++wait is satisfied. Both the initial and maximum count are established
++when the semaphore is created.
++
++A mutex holds a volatile 32-bit recursion count, and a volatile 32-bit
++identifier denoting its owner. A mutex is considered signaled when its
++owner is zero (indicating that it is not owned). The recursion count
++is incremented when a wait is satisfied, and ownership is set to the
++given identifier.
++
++A mutex also holds an internal flag denoting whether its previous
++owner has died; such a mutex is said to be inconsistent. Owner death
++is not tracked automatically based on thread death, but rather must be
++communicated using ``NTSYNC_IOC_KILL_OWNER``. An inconsistent mutex
++is inherently considered unowned.
++
++Except for the "unowned" semantics of zero, the actual value of the
++owner identifier is not interpreted by the ntsync driver at all. The
++intended use is to store a thread identifier; however, the ntsync
++driver does not actually validate that a calling thread provides
++consistent or unique identifiers.
++
++An event holds a volatile boolean state denoting whether it is
++signaled or not. There are two types of events, auto-reset and
++manual-reset. An auto-reset event is designaled when a wait is
++satisfied; a manual-reset event is not. The event type is specified
++when the event is created.
++
++Unless specified otherwise, all operations on an object are atomic and
++totally ordered with respect to other operations on the same object.
++
++Objects are represented by unsigned 32-bit integers.
++
++Char device
++===========
++
++The ntsync driver creates a single char device /dev/ntsync. Each
++file description opened on the device represents a unique namespace.
++That is, objects created on one open file description are shared
++across all its individual descriptors, but are not shared with other
++open() calls on the same device. The same file description may be
++shared across multiple processes.
++
++ioctl reference
++===============
++
++All operations on the device are done through ioctls. There are four
++structures used in ioctl calls::
++
++ struct ntsync_sem_args {
++ __u32 sem;
++ __u32 count;
++ __u32 max;
++ };
++
++ struct ntsync_mutex_args {
++ __u32 mutex;
++ __u32 owner;
++ __u32 count;
++ };
++
++ struct ntsync_event_args {
++ __u32 event;
++ __u32 signaled;
++ __u32 manual;
++ };
++
++ struct ntsync_wait_args {
++ __u64 timeout;
++ __u64 objs;
++ __u32 count;
++ __u32 owner;
++ __u32 index;
++ __u32 alert;
++ };
++
++Depending on the ioctl, members of the structure may be used as input,
++output, or not at all. All ioctls return 0 on success.
++
++The ioctls are as follows:
++
++.. c:macro:: NTSYNC_IOC_CREATE_SEM
++
++ Create a semaphore object. Takes a pointer to struct
++ :c:type:`ntsync_sem_args`, which is used as follows:
++
++ .. list-table::
++
++ * - ``sem``
++ - On output, contains the identifier of the created semaphore.
++ * - ``count``
++ - Initial count of the semaphore.
++ * - ``max``
++ - Maximum count of the semaphore.
++
++ Fails with ``EINVAL`` if ``count`` is greater than ``max``.
++
++.. c:macro:: NTSYNC_IOC_CREATE_MUTEX
++
++ Create a mutex object. Takes a pointer to struct
++ :c:type:`ntsync_mutex_args`, which is used as follows:
++
++ .. list-table::
++
++ * - ``mutex``
++ - On output, contains the identifier of the created mutex.
++ * - ``count``
++ - Initial recursion count of the mutex.
++ * - ``owner``
++ - Initial owner of the mutex.
++
++ If ``owner`` is nonzero and ``count`` is zero, or if ``owner`` is
++ zero and ``count`` is nonzero, the function fails with ``EINVAL``.
++
++.. c:macro:: NTSYNC_IOC_CREATE_EVENT
++
++ Create an event object. Takes a pointer to struct
++ :c:type:`ntsync_event_args`, which is used as follows:
++
++ .. list-table::
++
++ * - ``event``
++ - On output, contains the identifier of the created event.
++ * - ``signaled``
++ - If nonzero, the event is initially signaled, otherwise
++ nonsignaled.
++ * - ``manual``
++ - If nonzero, the event is a manual-reset event, otherwise
++ auto-reset.
++
++.. c:macro:: NTSYNC_IOC_DELETE
++
++ Delete an object of any type. Takes an input-only pointer to a
++ 32-bit integer denoting the object to delete.
++
++ Wait ioctls currently in progress are not interrupted, and behave as
++ if the object remains valid.
++
++.. c:macro:: NTSYNC_IOC_PUT_SEM
++
++ Post to a semaphore object. Takes a pointer to struct
++ :c:type:`ntsync_sem_args`, which is used as follows:
++
++ .. list-table::
++
++ * - ``sem``
++ - Semaphore object to post to.
++ * - ``count``
++ - Count to add to the semaphore. On output, contains the
++ previous count of the semaphore.
++ * - ``max``
++ - Not used.
++
++ If adding ``count`` to the semaphore's current count would raise the
++ latter past the semaphore's maximum count, the ioctl fails with
++ ``EOVERFLOW`` and the semaphore is not affected. If raising the
++ semaphore's count causes it to become signaled, eligible threads
++ waiting on this semaphore will be woken and the semaphore's count
++ decremented appropriately.
++
++.. c:macro:: NTSYNC_IOC_PUT_MUTEX
++
++ Release a mutex object. Takes a pointer to struct
++ :c:type:`ntsync_mutex_args`, which is used as follows:
++
++ .. list-table::
++
++ * - ``mutex``
++ - Mutex object to release.
++ * - ``owner``
++ - Mutex owner identifier.
++ * - ``count``
++ - On output, contains the previous recursion count.
++
++ If ``owner`` is zero, the ioctl fails with ``EINVAL``. If ``owner``
++ is not the current owner of the mutex, the ioctl fails with
++ ``EPERM``.
++
++ The mutex's count will be decremented by one. If decrementing the
++ mutex's count causes it to become zero, the mutex is marked as
++ unowned and signaled, and eligible threads waiting on it will be
++ woken as appropriate.
++
++.. c:macro:: NTSYNC_IOC_SET_EVENT
++
++ Signal an event object. Takes a pointer to struct
++ :c:type:`ntsync_event_args`, which is used as follows:
++
++ .. list-table::
++
++ * - ``event``
++ - Event object to set.
++ * - ``signaled``
++ - On output, contains the previous state of the event.
++ * - ``manual``
++ - Unused.
++
++ Eligible threads will be woken, and auto-reset events will be
++ designaled appropriately.
++
++.. c:macro:: NTSYNC_IOC_RESET_EVENT
++
++ Designal an event object. Takes a pointer to struct
++ :c:type:`ntsync_event_args`, which is used as follows:
++
++ .. list-table::
++
++ * - ``event``
++ - Event object to reset.
++ * - ``signaled``
++ - On output, contains the previous state of the event.
++ * - ``manual``
++ - Unused.
++
++.. c:macro:: NTSYNC_IOC_PULSE_EVENT
++
++ Wake threads waiting on an event object without leaving it in a
++ signaled state. Takes a pointer to struct
++ :c:type:`ntsync_event_args`, which is used as follows:
++
++ .. list-table::
++
++ * - ``event``
++ - Event object to pulse.
++ * - ``signaled``
++ - On output, contains the previous state of the event.
++ * - ``manual``
++ - Unused.
++
++ A pulse operation can be thought of as a set followed by a reset,
++ performed as a single atomic operation. If two threads are waiting
++ on an auto-reset event which is pulsed, only one will be woken. If
++ two threads are waiting a manual-reset event which is pulsed, both
++ will be woken. However, in both cases, the event will be unsignaled
++ afterwards, and a simultaneous read operation will always report the
++ event as unsignaled.
++
++.. c:macro:: NTSYNC_IOC_READ_SEM
++
++ Read the current state of a semaphore object. Takes a pointer to
++ struct :c:type:`ntsync_sem_args`, which is used as follows:
++
++ .. list-table::
++
++ * - ``sem``
++ - Semaphore object to read.
++ * - ``count``
++ - On output, contains the current count of the semaphore.
++ * - ``max``
++ - On output, contains the maximum count of the semaphore.
++
++.. c:macro:: NTSYNC_IOC_READ_MUTEX
++
++ Read the current state of a mutex object. Takes a pointer to struct
++ :c:type:`ntsync_mutex_args`, which is used as follows:
++
++ .. list-table::
++
++ * - ``mutex``
++ - Mutex object to read.
++ * - ``owner``
++ - On output, contains the current owner of the mutex, or zero
++ if the mutex is not currently owned.
++ * - ``count``
++ - On output, contains the current recursion count of the mutex.
++
++ If the mutex is marked as inconsistent, the function fails with
++ ``EOWNERDEAD``. In this case, ``count`` and ``owner`` are set to
++ zero.
++
++.. c:macro:: NTSYNC_IOC_READ_EVENT
++
++ Read the current state of an event object. Takes a pointer to struct
++ :c:type:`ntsync_event_args`, which is used as follows:
++
++ .. list-table::
++
++ * - ``event``
++ - Event object.
++ * - ``signaled``
++ - On output, contains the current state of the event.
++ * - ``manual``
++ - On output, contains 1 if the event is a manual-reset event,
++ and 0 otherwise.
++
++.. c:macro:: NTSYNC_IOC_KILL_OWNER
++
++ Mark any mutexes owned by the given owner as unowned and
++ inconsistent. Takes an input-only pointer to a 32-bit integer
++ denoting the owner. If the owner is zero, the ioctl fails with
++ ``EINVAL``.
++
++ For each mutex currently owned by the given owner, eligible threads
++ waiting on said mutex will be woken as appropriate (and such waits
++ will fail with ``EOWNERDEAD``, as described below).
++
++ The operation as a whole is not atomic; however, the modification of
++ each mutex is atomic and totally ordered with respect to other
++ operations on the same mutex.
++
++.. c:macro:: NTSYNC_IOC_WAIT_ANY
++
++ Poll on any of a list of objects, atomically acquiring at most one.
++ Takes a pointer to struct :c:type:`ntsync_wait_args`, which is
++ used as follows:
++
++ .. list-table::
++
++ * - ``timeout``
++ - Optional pointer to a 64-bit struct :c:type:`timespec`
++ (specified as an integer so that the structure has the same
++ size regardless of architecture). The timeout is specified in
++ absolute format, as measured against the MONOTONIC clock. If
++ the timeout is equal to or earlier than the current time, the
++ function returns immediately without sleeping. If ``timeout``
++ is zero, i.e. NULL, the function will sleep until an object
++ is signaled, and will not fail with ``ETIMEDOUT``.
++ * - ``objs``
++ - Pointer to an array of ``count`` 32-bit object identifiers
++ (specified as an integer so that the structure has the same
++ size regardless of architecture). If any identifier is
++ invalid, the function fails with ``EINVAL``.
++ * - ``count``
++ - Number of object identifiers specified in the ``objs`` array.
++ If greater than ``NTSYNC_MAX_WAIT_COUNT``, the function fails
++ with ``EINVAL``.
++ * - ``owner``
++ - Mutex owner identifier. If any object in ``objs`` is a mutex,
++ the ioctl will attempt to acquire that mutex on behalf of
++ ``owner``. If ``owner`` is zero, the ioctl fails with
++ ``EINVAL``.
++ * - ``index``
++ - On success, contains the index (into ``objs``) of the object
+ which was signaled. If ``alert`` was signaled instead,
+ this contains ``count``.
+ * - ``alert``
@@ -5047,16 +4909,34 @@ index ffa2f8fbc7e3..f0110d2744c7 100644
+ an "alert" event object which, if signaled, will terminate
+ the wait. If nonzero, the identifier must point to a valid
+ event.
-
- This function attempts to acquire one of the given objects. If
- unable to do so, it sleeps until an object becomes signaled,
-@@ -385,9 +389,19 @@ The ioctls are as follows:
- the given owner (with a recursion count of 1) and as no longer
- inconsistent, and ``index`` is still set to the index of the mutex.
-
-- It is valid to pass the same object more than once. If a wakeup
-- occurs due to that object being signaled, ``index`` is set to the
-- lowest index corresponding to that object.
++
++ This function attempts to acquire one of the given objects. If
++ unable to do so, it sleeps until an object becomes signaled,
++ subsequently acquiring it, or the timeout expires. In the latter
++ case the ioctl fails with ``ETIMEDOUT``. The function only acquires
++ one object, even if multiple objects are signaled.
++
++ A semaphore is considered to be signaled if its count is nonzero,
++ and is acquired by decrementing its count by one. A mutex is
++ considered to be signaled if it is unowned or if its owner matches
++ the ``owner`` argument, and is acquired by incrementing its
++ recursion count by one and setting its owner to the ``owner``
++ argument. An auto-reset event is acquired by designaling it; a
++ manual-reset event is not affected by acquisition.
++
++ Acquisition is atomic and totally ordered with respect to other
++ operations on the same object. If two wait operations (with
++ different ``owner`` identifiers) are queued on the same mutex, only
++ one is signaled. If two wait operations are queued on the same
++ semaphore, and a value of one is posted to it, only one is signaled.
++ The order in which threads are signaled is not specified.
++
++ If an inconsistent mutex is acquired, the ioctl fails with
++ ``EOWNERDEAD``. Although this is a failure return, the function may
++ otherwise be considered successful. The mutex is marked as owned by
++ the given owner (with a recursion count of 1) and as no longer
++ inconsistent, and ``index`` is still set to the index of the mutex.
++
+ The ``alert`` argument is an "extra" event which can terminate the
+ wait, independently of all other objects. If members of ``objs`` and
+ ``alert`` are both simultaneously signaled, a member of ``objs``
@@ -5070,22 +4950,35 @@ index ffa2f8fbc7e3..f0110d2744c7 100644
+ passing the same event in the ``objs`` array and in ``alert``. If a
+ wakeup occurs due to that object being signaled, ``index`` is set to
+ the lowest index corresponding to that object.
-
- The function may fail with ``EINTR`` if a signal is received.
-
-@@ -396,7 +410,7 @@ The ioctls are as follows:
- Poll on a list of objects, atomically acquiring all of them. Takes a
- pointer to struct :c:type:`winesync_wait_args`, which is used
- identically to ``WINESYNC_IOC_WAIT_ANY``, except that ``index`` is
-- always filled with zero on success.
++
++ The function may fail with ``EINTR`` if a signal is received.
++
++.. c:macro:: NTSYNC_IOC_WAIT_ALL
++
++ Poll on a list of objects, atomically acquiring all of them. Takes a
++ pointer to struct :c:type:`ntsync_wait_args`, which is used
++ identically to ``NTSYNC_IOC_WAIT_ANY``, except that ``index`` is
+ always filled with zero on success if not woken via alert.
-
- This function attempts to simultaneously acquire all of the given
- objects. If unable to do so, it sleeps until all objects become
-@@ -417,6 +431,14 @@ The ioctls are as follows:
- objects are specified, there is no way to know which were marked as
- inconsistent.
-
++
++ This function attempts to simultaneously acquire all of the given
++ objects. If unable to do so, it sleeps until all objects become
++ simultaneously signaled, subsequently acquiring them, or the timeout
++ expires. In the latter case the ioctl fails with ``ETIMEDOUT`` and
++ no objects are modified.
++
++ Objects may become signaled and subsequently designaled (through
++ acquisition by other threads) while this thread is sleeping. Only
++ once all objects are simultaneously signaled does the ioctl acquire
++ them and return. The entire acquisition is atomic and totally
++ ordered with respect to other operations on any of the given
++ objects.
++
++ If an inconsistent mutex is acquired, the ioctl fails with
++ ``EOWNERDEAD``. Similarly to ``NTSYNC_IOC_WAIT_ANY``, all objects
++ are nevertheless marked as acquired. Note that if multiple mutex
++ objects are specified, there is no way to know which were marked as
++ inconsistent.
++
+ As with "any" waits, the ``alert`` argument is an "extra" event
+ which can terminate the wait. Critically, however, an "all" wait
+ will succeed if all members in ``objs`` are signaled, *or* if
@@ -5093,12 +4986,10 @@ index ffa2f8fbc7e3..f0110d2744c7 100644
+ ``count``. As with "any" waits, if both conditions are filled, the
+ former takes priority, and objects in ``objs`` will be acquired.
+
- Unlike ``WINESYNC_IOC_WAIT_ANY``, it is not valid to pass the same
-- object more than once. If this is attempted, the function fails with
-- ``EINVAL``.
++ Unlike ``NTSYNC_IOC_WAIT_ANY``, it is not valid to pass the same
+ object more than once, nor is it valid to pass the same object in
-+ ``objs`` and in ``alert`` If this is attempted, the function fails
++ ``objs`` and in ``alert``. If this is attempted, the function fails
+ with ``EINVAL``.
--
-2.36.0
+2.43.0
diff --git a/SOURCES/kernel-aarch64-16k-debug-fedora.config b/SOURCES/kernel-aarch64-16k-debug-fedora.config
index bd4f041..9ff368c 100644
--- a/SOURCES/kernel-aarch64-16k-debug-fedora.config
+++ b/SOURCES/kernel-aarch64-16k-debug-fedora.config
@@ -9956,7 +9956,7 @@ CONFIG_ZYNQMP_PM_DOMAINS=y
CONFIG_ZYNQMP_POWER=y
CONFIG_I2C_NCT6775=m
CONFIG_ZENIFY=y
-CONFIG_WINESYNC=y
+CONFIG_NTSYNC=y
CONFIG_USER_NS_UNPRIVILEGED=y
CONFIG_TCP_CONG_BBR2=m
CONFIG_HID_IPTS=m
diff --git a/SOURCES/kernel-aarch64-16k-fedora.config b/SOURCES/kernel-aarch64-16k-fedora.config
index ec61b3f..4a2d617 100644
--- a/SOURCES/kernel-aarch64-16k-fedora.config
+++ b/SOURCES/kernel-aarch64-16k-fedora.config
@@ -9927,7 +9927,7 @@ CONFIG_ZYNQMP_PM_DOMAINS=y
CONFIG_ZYNQMP_POWER=y
CONFIG_I2C_NCT6775=m
CONFIG_ZENIFY=y
-CONFIG_WINESYNC=y
+CONFIG_NTSYNC=y
CONFIG_USER_NS_UNPRIVILEGED=y
CONFIG_TCP_CONG_BBR2=m
CONFIG_HID_IPTS=m
diff --git a/SOURCES/kernel-aarch64-64k-debug-rhel.config b/SOURCES/kernel-aarch64-64k-debug-rhel.config
index 8b16e57..5350ae9 100644
--- a/SOURCES/kernel-aarch64-64k-debug-rhel.config
+++ b/SOURCES/kernel-aarch64-64k-debug-rhel.config
@@ -8044,7 +8044,7 @@ CONFIG_ZSWAP_ZPOOL_DEFAULT_ZBUD=y
# CONFIG_ZSWAP_ZPOOL_DEFAULT_ZSMALLOC is not set
CONFIG_I2C_NCT6775=m
CONFIG_ZENIFY=y
-CONFIG_WINESYNC=y
+CONFIG_NTSYNC=y
CONFIG_USER_NS_UNPRIVILEGED=y
CONFIG_TCP_CONG_BBR2=m
CONFIG_HID_IPTS=m
diff --git a/SOURCES/kernel-aarch64-64k-rhel.config b/SOURCES/kernel-aarch64-64k-rhel.config
index 14aa64a..4186861 100644
--- a/SOURCES/kernel-aarch64-64k-rhel.config
+++ b/SOURCES/kernel-aarch64-64k-rhel.config
@@ -8019,7 +8019,7 @@ CONFIG_ZSWAP_ZPOOL_DEFAULT_ZBUD=y
# CONFIG_ZSWAP_ZPOOL_DEFAULT_ZSMALLOC is not set
CONFIG_I2C_NCT6775=m
CONFIG_ZENIFY=y
-CONFIG_WINESYNC=y
+CONFIG_NTSYNC=y
CONFIG_USER_NS_UNPRIVILEGED=y
CONFIG_TCP_CONG_BBR2=m
CONFIG_HID_IPTS=m
diff --git a/SOURCES/kernel-aarch64-debug-fedora.config b/SOURCES/kernel-aarch64-debug-fedora.config
index 4eaf2fc..f94d35a 100644
--- a/SOURCES/kernel-aarch64-debug-fedora.config
+++ b/SOURCES/kernel-aarch64-debug-fedora.config
@@ -9956,7 +9956,7 @@ CONFIG_ZYNQMP_PM_DOMAINS=y
CONFIG_ZYNQMP_POWER=y
CONFIG_I2C_NCT6775=m
CONFIG_ZENIFY=y
-CONFIG_WINESYNC=y
+CONFIG_NTSYNC=y
CONFIG_USER_NS_UNPRIVILEGED=y
CONFIG_TCP_CONG_BBR2=m
CONFIG_HID_IPTS=m
diff --git a/SOURCES/kernel-aarch64-debug-rhel.config b/SOURCES/kernel-aarch64-debug-rhel.config
index bae5983..07cd10c 100644
--- a/SOURCES/kernel-aarch64-debug-rhel.config
+++ b/SOURCES/kernel-aarch64-debug-rhel.config
@@ -8040,7 +8040,7 @@ CONFIG_ZSWAP_ZPOOL_DEFAULT_ZBUD=y
# CONFIG_ZSWAP_ZPOOL_DEFAULT_ZSMALLOC is not set
CONFIG_I2C_NCT6775=m
CONFIG_ZENIFY=y
-CONFIG_WINESYNC=y
+CONFIG_NTSYNC=y
CONFIG_USER_NS_UNPRIVILEGED=y
CONFIG_TCP_CONG_BBR2=m
CONFIG_HID_IPTS=m
diff --git a/SOURCES/kernel-aarch64-fedora.config b/SOURCES/kernel-aarch64-fedora.config
index 7eb940a..738e4be 100644
--- a/SOURCES/kernel-aarch64-fedora.config
+++ b/SOURCES/kernel-aarch64-fedora.config
@@ -9927,7 +9927,7 @@ CONFIG_ZYNQMP_PM_DOMAINS=y
CONFIG_ZYNQMP_POWER=y
CONFIG_I2C_NCT6775=m
CONFIG_ZENIFY=y
-CONFIG_WINESYNC=y
+CONFIG_NTSYNC=y
CONFIG_USER_NS_UNPRIVILEGED=y
CONFIG_TCP_CONG_BBR2=m
CONFIG_HID_IPTS=m
diff --git a/SOURCES/kernel-aarch64-rhel.config b/SOURCES/kernel-aarch64-rhel.config
index 723a6e3..8d41ffa 100644
--- a/SOURCES/kernel-aarch64-rhel.config
+++ b/SOURCES/kernel-aarch64-rhel.config
@@ -8015,7 +8015,7 @@ CONFIG_ZSWAP_ZPOOL_DEFAULT_ZBUD=y
# CONFIG_ZSWAP_ZPOOL_DEFAULT_ZSMALLOC is not set
CONFIG_I2C_NCT6775=m
CONFIG_ZENIFY=y
-CONFIG_WINESYNC=y
+CONFIG_NTSYNC=y
CONFIG_USER_NS_UNPRIVILEGED=y
CONFIG_TCP_CONG_BBR2=m
CONFIG_HID_IPTS=m
diff --git a/SOURCES/kernel-aarch64-rt-debug-rhel.config b/SOURCES/kernel-aarch64-rt-debug-rhel.config
index 6802b3d..6ff8207 100644
--- a/SOURCES/kernel-aarch64-rt-debug-rhel.config
+++ b/SOURCES/kernel-aarch64-rt-debug-rhel.config
@@ -8100,7 +8100,7 @@ CONFIG_ZSWAP_ZPOOL_DEFAULT_ZBUD=y
# CONFIG_ZSWAP_ZPOOL_DEFAULT_ZSMALLOC is not set
CONFIG_I2C_NCT6775=m
CONFIG_ZENIFY=y
-CONFIG_WINESYNC=y
+CONFIG_NTSYNC=y
CONFIG_USER_NS_UNPRIVILEGED=y
CONFIG_TCP_CONG_BBR2=m
CONFIG_HID_IPTS=m
diff --git a/SOURCES/kernel-aarch64-rt-rhel.config b/SOURCES/kernel-aarch64-rt-rhel.config
index cb5df81..4f7912e 100644
--- a/SOURCES/kernel-aarch64-rt-rhel.config
+++ b/SOURCES/kernel-aarch64-rt-rhel.config
@@ -8075,7 +8075,7 @@ CONFIG_ZSWAP_ZPOOL_DEFAULT_ZBUD=y
# CONFIG_ZSWAP_ZPOOL_DEFAULT_ZSMALLOC is not set
CONFIG_I2C_NCT6775=m
CONFIG_ZENIFY=y
-CONFIG_WINESYNC=y
+CONFIG_NTSYNC=y
CONFIG_USER_NS_UNPRIVILEGED=y
CONFIG_TCP_CONG_BBR2=m
CONFIG_HID_IPTS=m
diff --git a/SOURCES/kernel-ppc64le-debug-fedora.config b/SOURCES/kernel-ppc64le-debug-fedora.config
index 7982fad..972cfc8 100644
--- a/SOURCES/kernel-ppc64le-debug-fedora.config
+++ b/SOURCES/kernel-ppc64le-debug-fedora.config
@@ -8263,7 +8263,7 @@ CONFIG_ZSWAP_ZPOOL_DEFAULT_ZBUD=y
# CONFIG_ZSWAP_ZPOOL_DEFAULT_ZSMALLOC is not set
CONFIG_I2C_NCT6775=m
CONFIG_ZENIFY=y
-CONFIG_WINESYNC=y
+CONFIG_NTSYNC=y
CONFIG_USER_NS_UNPRIVILEGED=y
CONFIG_TCP_CONG_BBR2=m
CONFIG_HID_IPTS=m
diff --git a/SOURCES/kernel-ppc64le-debug-rhel.config b/SOURCES/kernel-ppc64le-debug-rhel.config
index 7fde4dc..bb0d6df 100644
--- a/SOURCES/kernel-ppc64le-debug-rhel.config
+++ b/SOURCES/kernel-ppc64le-debug-rhel.config
@@ -7509,7 +7509,7 @@ CONFIG_ZSWAP_ZPOOL_DEFAULT_ZBUD=y
# CONFIG_ZSWAP_ZPOOL_DEFAULT_ZSMALLOC is not set
CONFIG_I2C_NCT6775=m
CONFIG_ZENIFY=y
-CONFIG_WINESYNC=y
+CONFIG_NTSYNC=y
CONFIG_USER_NS_UNPRIVILEGED=y
CONFIG_TCP_CONG_BBR2=m
CONFIG_HID_IPTS=m
diff --git a/SOURCES/kernel-ppc64le-fedora.config b/SOURCES/kernel-ppc64le-fedora.config
index 21b92d4..f3382b9 100644
--- a/SOURCES/kernel-ppc64le-fedora.config
+++ b/SOURCES/kernel-ppc64le-fedora.config
@@ -8232,7 +8232,7 @@ CONFIG_ZSWAP_ZPOOL_DEFAULT_ZBUD=y
# CONFIG_ZSWAP_ZPOOL_DEFAULT_ZSMALLOC is not set
CONFIG_I2C_NCT6775=m
CONFIG_ZENIFY=y
-CONFIG_WINESYNC=y
+CONFIG_NTSYNC=y
CONFIG_USER_NS_UNPRIVILEGED=y
CONFIG_TCP_CONG_BBR2=m
CONFIG_HID_IPTS=m
diff --git a/SOURCES/kernel-ppc64le-rhel.config b/SOURCES/kernel-ppc64le-rhel.config
index dfad115..dc57e1d 100644
--- a/SOURCES/kernel-ppc64le-rhel.config
+++ b/SOURCES/kernel-ppc64le-rhel.config
@@ -7486,7 +7486,7 @@ CONFIG_ZSWAP_ZPOOL_DEFAULT_ZBUD=y
# CONFIG_ZSWAP_ZPOOL_DEFAULT_ZSMALLOC is not set
CONFIG_I2C_NCT6775=m
CONFIG_ZENIFY=y
-CONFIG_WINESYNC=y
+CONFIG_NTSYNC=y
CONFIG_USER_NS_UNPRIVILEGED=y
CONFIG_TCP_CONG_BBR2=m
CONFIG_HID_IPTS=m
diff --git a/SOURCES/kernel-s390x-debug-fedora.config b/SOURCES/kernel-s390x-debug-fedora.config
index fe00aca..ea107d3 100644
--- a/SOURCES/kernel-s390x-debug-fedora.config
+++ b/SOURCES/kernel-s390x-debug-fedora.config
@@ -8199,7 +8199,7 @@ CONFIG_ZSWAP_ZPOOL_DEFAULT_ZBUD=y
# CONFIG_ZSWAP_ZPOOL_DEFAULT_ZSMALLOC is not set
CONFIG_I2C_NCT6775=m
CONFIG_ZENIFY=y
-CONFIG_WINESYNC=y
+CONFIG_NTSYNC=y
CONFIG_USER_NS_UNPRIVILEGED=y
CONFIG_TCP_CONG_BBR2=m
CONFIG_HID_IPTS=m
diff --git a/SOURCES/kernel-s390x-debug-rhel.config b/SOURCES/kernel-s390x-debug-rhel.config
index b563264..c0f9b83 100644
--- a/SOURCES/kernel-s390x-debug-rhel.config
+++ b/SOURCES/kernel-s390x-debug-rhel.config
@@ -7492,7 +7492,7 @@ CONFIG_ZSWAP_ZPOOL_DEFAULT_ZBUD=y
# CONFIG_ZSWAP_ZPOOL_DEFAULT_ZSMALLOC is not set
CONFIG_I2C_NCT6775=m
CONFIG_ZENIFY=y
-CONFIG_WINESYNC=y
+CONFIG_NTSYNC=y
CONFIG_USER_NS_UNPRIVILEGED=y
CONFIG_TCP_CONG_BBR2=m
CONFIG_HID_IPTS=m
diff --git a/SOURCES/kernel-s390x-fedora.config b/SOURCES/kernel-s390x-fedora.config
index 1507306..e61d28b 100644
--- a/SOURCES/kernel-s390x-fedora.config
+++ b/SOURCES/kernel-s390x-fedora.config
@@ -8168,7 +8168,7 @@ CONFIG_ZSWAP_ZPOOL_DEFAULT_ZBUD=y
# CONFIG_ZSWAP_ZPOOL_DEFAULT_ZSMALLOC is not set
CONFIG_I2C_NCT6775=m
CONFIG_ZENIFY=y
-CONFIG_WINESYNC=y
+CONFIG_NTSYNC=y
CONFIG_USER_NS_UNPRIVILEGED=y
CONFIG_TCP_CONG_BBR2=m
CONFIG_HID_IPTS=m
diff --git a/SOURCES/kernel-s390x-rhel.config b/SOURCES/kernel-s390x-rhel.config
index 6af13b4..654b6ca 100644
--- a/SOURCES/kernel-s390x-rhel.config
+++ b/SOURCES/kernel-s390x-rhel.config
@@ -7469,7 +7469,7 @@ CONFIG_ZSWAP_ZPOOL_DEFAULT_ZBUD=y
# CONFIG_ZSWAP_ZPOOL_DEFAULT_ZSMALLOC is not set
CONFIG_I2C_NCT6775=m
CONFIG_ZENIFY=y
-CONFIG_WINESYNC=y
+CONFIG_NTSYNC=y
CONFIG_USER_NS_UNPRIVILEGED=y
CONFIG_TCP_CONG_BBR2=m
CONFIG_HID_IPTS=m
diff --git a/SOURCES/kernel-s390x-zfcpdump-rhel.config b/SOURCES/kernel-s390x-zfcpdump-rhel.config
index aa058bb..6840b0a 100644
--- a/SOURCES/kernel-s390x-zfcpdump-rhel.config
+++ b/SOURCES/kernel-s390x-zfcpdump-rhel.config
@@ -7492,7 +7492,7 @@ CONFIG_ZSWAP_ZPOOL_DEFAULT_ZBUD=y
# CONFIG_ZSWAP_ZPOOL_DEFAULT_ZSMALLOC is not set
CONFIG_I2C_NCT6775=m
CONFIG_ZENIFY=y
-CONFIG_WINESYNC=y
+CONFIG_NTSYNC=y
CONFIG_USER_NS_UNPRIVILEGED=y
CONFIG_TCP_CONG_BBR2=m
CONFIG_HID_IPTS=m
diff --git a/SOURCES/kernel-x86_64-debug-fedora.config b/SOURCES/kernel-x86_64-debug-fedora.config
index 1a2d8b0..c53228e 100644
--- a/SOURCES/kernel-x86_64-debug-fedora.config
+++ b/SOURCES/kernel-x86_64-debug-fedora.config
@@ -8847,7 +8847,7 @@ CONFIG_ZSWAP_ZPOOL_DEFAULT_ZBUD=y
# CONFIG_ZSWAP_ZPOOL_DEFAULT_ZSMALLOC is not set
CONFIG_I2C_NCT6775=m
CONFIG_ZENIFY=y
-CONFIG_WINESYNC=y
+CONFIG_NTSYNC=y
CONFIG_USER_NS_UNPRIVILEGED=y
CONFIG_TCP_CONG_BBR2=m
CONFIG_HID_IPTS=m
diff --git a/SOURCES/kernel-x86_64-debug-rhel.config b/SOURCES/kernel-x86_64-debug-rhel.config
index a907156..3e6acda 100644
--- a/SOURCES/kernel-x86_64-debug-rhel.config
+++ b/SOURCES/kernel-x86_64-debug-rhel.config
@@ -7842,7 +7842,7 @@ CONFIG_ZSWAP_ZPOOL_DEFAULT_ZBUD=y
# CONFIG_ZSWAP_ZPOOL_DEFAULT_ZSMALLOC is not set
CONFIG_I2C_NCT6775=m
CONFIG_ZENIFY=y
-CONFIG_WINESYNC=y
+CONFIG_NTSYNC=y
CONFIG_USER_NS_UNPRIVILEGED=y
CONFIG_TCP_CONG_BBR2=m
CONFIG_HID_IPTS=m
diff --git a/SOURCES/kernel-x86_64-fedora.config b/SOURCES/kernel-x86_64-fedora.config
index a1ba3a8..6b6f84a 100644
--- a/SOURCES/kernel-x86_64-fedora.config
+++ b/SOURCES/kernel-x86_64-fedora.config
@@ -8817,7 +8817,7 @@ CONFIG_ZSWAP_ZPOOL_DEFAULT_ZBUD=y
# CONFIG_ZSWAP_ZPOOL_DEFAULT_ZSMALLOC is not set
CONFIG_I2C_NCT6775=m
CONFIG_ZENIFY=y
-CONFIG_WINESYNC=y
+CONFIG_NTSYNC=y
CONFIG_USER_NS_UNPRIVILEGED=y
CONFIG_TCP_CONG_BBR2=m
CONFIG_HID_IPTS=m
diff --git a/SOURCES/kernel-x86_64-rhel.config b/SOURCES/kernel-x86_64-rhel.config
index 1c6c754..60ae0b8 100644
--- a/SOURCES/kernel-x86_64-rhel.config
+++ b/SOURCES/kernel-x86_64-rhel.config
@@ -7818,7 +7818,7 @@ CONFIG_ZSWAP_ZPOOL_DEFAULT_ZBUD=y
# CONFIG_ZSWAP_ZPOOL_DEFAULT_ZSMALLOC is not set
CONFIG_I2C_NCT6775=m
CONFIG_ZENIFY=y
-CONFIG_WINESYNC=y
+CONFIG_NTSYNC=y
CONFIG_USER_NS_UNPRIVILEGED=y
CONFIG_TCP_CONG_BBR2=m
CONFIG_HID_IPTS=m
diff --git a/SOURCES/kernel-x86_64-rt-debug-rhel.config b/SOURCES/kernel-x86_64-rt-debug-rhel.config
index cdf65b7..5f037bb 100644
--- a/SOURCES/kernel-x86_64-rt-debug-rhel.config
+++ b/SOURCES/kernel-x86_64-rt-debug-rhel.config
@@ -7903,7 +7903,7 @@ CONFIG_ZSWAP_ZPOOL_DEFAULT_ZBUD=y
# CONFIG_ZSWAP_ZPOOL_DEFAULT_ZSMALLOC is not set
CONFIG_I2C_NCT6775=m
CONFIG_ZENIFY=y
-CONFIG_WINESYNC=y
+CONFIG_NTSYNC=y
CONFIG_USER_NS_UNPRIVILEGED=y
CONFIG_TCP_CONG_BBR2=m
CONFIG_HID_IPTS=m
diff --git a/SOURCES/kernel-x86_64-rt-rhel.config b/SOURCES/kernel-x86_64-rt-rhel.config
index 8f7d92f..2fcde56 100644
--- a/SOURCES/kernel-x86_64-rt-rhel.config
+++ b/SOURCES/kernel-x86_64-rt-rhel.config
@@ -7879,7 +7879,7 @@ CONFIG_ZSWAP_ZPOOL_DEFAULT_ZBUD=y
# CONFIG_ZSWAP_ZPOOL_DEFAULT_ZSMALLOC is not set
CONFIG_I2C_NCT6775=m
CONFIG_ZENIFY=y
-CONFIG_WINESYNC=y
+CONFIG_NTSYNC=y
CONFIG_USER_NS_UNPRIVILEGED=y
CONFIG_TCP_CONG_BBR2=m
CONFIG_HID_IPTS=m
diff --git a/SOURCES/kernel.changelog b/SOURCES/kernel.changelog
index 6cb5d52..c40dbe9 100644
--- a/SOURCES/kernel.changelog
+++ b/SOURCES/kernel.changelog
@@ -1,3 +1,8 @@
+* Fri Feb 23 2024 Justin M. Forbes <jforbes@fedoraproject.org> [6.7.6-0]
+- Add CVE fix for 6.7.6 (Justin M. Forbes)
+- Linux v6.7.6
+Resolves:
+
* Sat Feb 17 2024 Justin M. Forbes <jforbes@fedoraproject.org> [6.7.5-0]
- Backported some CVE fixes lets note them in BugsFixed (Justin M. Forbes)
- selftests: openvswitch: Add validation for the recursion test (Aaron Conole)
diff --git a/SOURCES/patch-6.7-redhat.patch b/SOURCES/patch-6.7-redhat.patch
index 8ba4339..0a7703b 100644
--- a/SOURCES/patch-6.7-redhat.patch
+++ b/SOURCES/patch-6.7-redhat.patch
@@ -16,23 +16,17 @@
drivers/firmware/sysfb.c | 18 ++-
drivers/gpu/drm/amd/amdgpu/amdgpu.h | 2 +
drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c | 15 ++
- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 12 +-
- drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c | 9 +-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 11 +-
drivers/hid/hid-rmi.c | 66 --------
drivers/hwtracing/coresight/coresight-etm4x-core.c | 19 +++
drivers/input/keyboard/atkbd.c | 3 +-
drivers/input/rmi4/rmi_driver.c | 124 +++++++++------
drivers/iommu/iommu.c | 22 +++
- drivers/md/dm-core.h | 2 +
- drivers/md/dm-ioctl.c | 3 +-
- drivers/md/dm-table.c | 9 +-
drivers/net/wireless/ath/ath10k/wmi-tlv.c | 4 +
drivers/pci/quirks.c | 24 +++
drivers/platform/x86/thinkpad_acpi.c | 20 ++-
drivers/scsi/sd.c | 10 ++
drivers/usb/core/hub.c | 7 +
- fs/btrfs/transaction.c | 38 +----
- fs/smb/client/namespace.c | 16 ++
include/linux/efi.h | 22 ++-
include/linux/lsm_hook_defs.h | 2 +
include/linux/module.h | 1 +
@@ -41,7 +35,6 @@
include/linux/security.h | 5 +
kernel/module/main.c | 2 +
kernel/module/signing.c | 9 +-
- net/openvswitch/flow_netlink.c | 49 ++++--
scripts/mod/modpost.c | 8 +
scripts/tags.sh | 2 +
security/integrity/platform_certs/load_uefi.c | 6 +-
@@ -51,7 +44,7 @@
tools/power/cpupower/Makefile | 2 +-
.../selftests/net/openvswitch/openvswitch.sh | 13 ++
.../testing/selftests/net/openvswitch/ovs-dpctl.py | 71 +++++++--
- 53 files changed, 866 insertions(+), 253 deletions(-)
+ 46 files changed, 796 insertions(+), 196 deletions(-)
diff --git a/Documentation/admin-guide/laptops/thinkpad-acpi.rst b/Documentation/admin-guide/laptops/thinkpad-acpi.rst
index 98d304010170..7f674a6cfa8a 100644
@@ -79,7 +72,7 @@ index 98d304010170..7f674a6cfa8a 100644
0x1020 0x1F unknown
diff --git a/Makefile b/Makefile
-index 0f5bb9ddc98f..a46f4937fa26 100644
+index d07a8e0179ac..5779c09825d9 100644
--- a/Makefile
+++ b/Makefile
@@ -22,6 +22,18 @@ $(if $(filter __%, $(MAKECMDGOALS)), \
@@ -660,7 +653,7 @@ index 2deebece810e..cc21ed67a330 100644
+
#endif /* CONFIG_SUSPEND */
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
-index 5fe1df95dc38..7f48c7ec4136 100644
+index 19bc8d47317b..7f48c7ec4136 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -4441,13 +4441,15 @@ int amdgpu_device_prepare(struct drm_device *dev)
@@ -697,35 +690,6 @@ index 5fe1df95dc38..7f48c7ec4136 100644
}
/**
-@@ -4496,7 +4503,6 @@ int amdgpu_device_suspend(struct drm_device *dev, bool fbcon)
- drm_fb_helper_set_suspend_unlocked(adev_to_drm(adev)->fb_helper, true);
-
- cancel_delayed_work_sync(&adev->delayed_init_work);
-- flush_delayed_work(&adev->gfx.gfx_off_delay_work);
-
- amdgpu_ras_suspend(adev);
-
-diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
-index b9674c57c436..6ddc8e3360e2 100644
---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
-+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
-@@ -723,8 +723,15 @@ void amdgpu_gfx_off_ctrl(struct amdgpu_device *adev, bool enable)
-
- if (adev->gfx.gfx_off_req_count == 0 &&
- !adev->gfx.gfx_off_state) {
-- schedule_delayed_work(&adev->gfx.gfx_off_delay_work,
-+ /* If going to s2idle, no need to wait */
-+ if (adev->in_s0ix) {
-+ if (!amdgpu_dpm_set_powergating_by_smu(adev,
-+ AMD_IP_BLOCK_TYPE_GFX, true))
-+ adev->gfx.gfx_off_state = true;
-+ } else {
-+ schedule_delayed_work(&adev->gfx.gfx_off_delay_work,
- delay);
-+ }
- }
- } else {
- if (adev->gfx.gfx_off_req_count == 0) {
diff --git a/drivers/hid/hid-rmi.c b/drivers/hid/hid-rmi.c
index d4af17fdba46..154f0403cbf4 100644
--- a/drivers/hid/hid-rmi.c
@@ -1132,60 +1096,6 @@ index 33e2a9b5d339..6ae1abc3f11c 100644
/**
* iommu_setup_default_domain - Set the default_domain for the group
* @group: Group to change
-diff --git a/drivers/md/dm-core.h b/drivers/md/dm-core.h
-index 095b9b49aa82..e6757a30dcca 100644
---- a/drivers/md/dm-core.h
-+++ b/drivers/md/dm-core.h
-@@ -22,6 +22,8 @@
- #include "dm-ima.h"
-
- #define DM_RESERVED_MAX_IOS 1024
-+#define DM_MAX_TARGETS 1048576
-+#define DM_MAX_TARGET_PARAMS 1024
-
- struct dm_io;
-
-diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
-index e65058e0ed06..3b1ad7127cb8 100644
---- a/drivers/md/dm-ioctl.c
-+++ b/drivers/md/dm-ioctl.c
-@@ -1941,7 +1941,8 @@ static int copy_params(struct dm_ioctl __user *user, struct dm_ioctl *param_kern
- minimum_data_size - sizeof(param_kernel->version)))
- return -EFAULT;
-
-- if (param_kernel->data_size < minimum_data_size) {
-+ if (unlikely(param_kernel->data_size < minimum_data_size) ||
-+ unlikely(param_kernel->data_size > DM_MAX_TARGETS * DM_MAX_TARGET_PARAMS)) {
- DMERR("Invalid data size in the ioctl structure: %u",
- param_kernel->data_size);
- return -EINVAL;
-diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
-index 198d38b53322..08c9c20f9c66 100644
---- a/drivers/md/dm-table.c
-+++ b/drivers/md/dm-table.c
-@@ -129,7 +129,12 @@ static int alloc_targets(struct dm_table *t, unsigned int num)
- int dm_table_create(struct dm_table **result, blk_mode_t mode,
- unsigned int num_targets, struct mapped_device *md)
- {
-- struct dm_table *t = kzalloc(sizeof(*t), GFP_KERNEL);
-+ struct dm_table *t;
-+
-+ if (num_targets > DM_MAX_TARGETS)
-+ return -EOVERFLOW;
-+
-+ t = kzalloc(sizeof(*t), GFP_KERNEL);
-
- if (!t)
- return -ENOMEM;
-@@ -144,7 +149,7 @@ int dm_table_create(struct dm_table **result, blk_mode_t mode,
-
- if (!num_targets) {
- kfree(t);
-- return -ENOMEM;
-+ return -EOVERFLOW;
- }
-
- if (alloc_targets(t, num_targets)) {
diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.c b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
index 6b6aa3c36744..0ce08e9a0a3d 100644
--- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c
@@ -1310,10 +1220,10 @@ index 542a4bbb21bc..62161ceed2e2 100644
if (err)
goto err_out_driver;
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
-index ef8d9bda94ac..3fab06f3b43e 100644
+index 4854d883e601..e1ee781ca985 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
-@@ -5777,6 +5777,13 @@ static void hub_event(struct work_struct *work)
+@@ -5795,6 +5795,13 @@ static void hub_event(struct work_struct *work)
(u16) hub->change_bits[0],
(u16) hub->event_bits[0]);
@@ -1327,103 +1237,6 @@ index ef8d9bda94ac..3fab06f3b43e 100644
/* Lock the device, then check to see if we were
* disconnected while waiting for the lock to succeed. */
usb_lock_device(hdev);
-diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
-index 5b3333ceef04..c52807d97efa 100644
---- a/fs/btrfs/transaction.c
-+++ b/fs/btrfs/transaction.c
-@@ -564,56 +564,22 @@ static int btrfs_reserve_trans_metadata(struct btrfs_fs_info *fs_info,
- u64 num_bytes,
- u64 *delayed_refs_bytes)
- {
-- struct btrfs_block_rsv *delayed_refs_rsv = &fs_info->delayed_refs_rsv;
- struct btrfs_space_info *si = fs_info->trans_block_rsv.space_info;
-- u64 extra_delayed_refs_bytes = 0;
-- u64 bytes;
-+ u64 bytes = num_bytes + *delayed_refs_bytes;
- int ret;
-
-- /*
-- * If there's a gap between the size of the delayed refs reserve and
-- * its reserved space, than some tasks have added delayed refs or bumped
-- * its size otherwise (due to block group creation or removal, or block
-- * group item update). Also try to allocate that gap in order to prevent
-- * using (and possibly abusing) the global reserve when committing the
-- * transaction.
-- */
-- if (flush == BTRFS_RESERVE_FLUSH_ALL &&
-- !btrfs_block_rsv_full(delayed_refs_rsv)) {
-- spin_lock(&delayed_refs_rsv->lock);
-- if (delayed_refs_rsv->size > delayed_refs_rsv->reserved)
-- extra_delayed_refs_bytes = delayed_refs_rsv->size -
-- delayed_refs_rsv->reserved;
-- spin_unlock(&delayed_refs_rsv->lock);
-- }
--
-- bytes = num_bytes + *delayed_refs_bytes + extra_delayed_refs_bytes;
--
- /*
- * We want to reserve all the bytes we may need all at once, so we only
- * do 1 enospc flushing cycle per transaction start.
- */
- ret = btrfs_reserve_metadata_bytes(fs_info, si, bytes, flush);
-- if (ret == 0) {
-- if (extra_delayed_refs_bytes > 0)
-- btrfs_migrate_to_delayed_refs_rsv(fs_info,
-- extra_delayed_refs_bytes);
-- return 0;
-- }
--
-- if (extra_delayed_refs_bytes > 0) {
-- bytes -= extra_delayed_refs_bytes;
-- ret = btrfs_reserve_metadata_bytes(fs_info, si, bytes, flush);
-- if (ret == 0)
-- return 0;
-- }
-
- /*
- * If we are an emergency flush, which can steal from the global block
- * reserve, then attempt to not reserve space for the delayed refs, as
- * we will consume space for them from the global block reserve.
- */
-- if (flush == BTRFS_RESERVE_FLUSH_ALL_STEAL) {
-+ if (ret && flush == BTRFS_RESERVE_FLUSH_ALL_STEAL) {
- bytes -= *delayed_refs_bytes;
- *delayed_refs_bytes = 0;
- ret = btrfs_reserve_metadata_bytes(fs_info, si, bytes, flush);
-diff --git a/fs/smb/client/namespace.c b/fs/smb/client/namespace.c
-index a6968573b775..4a517b280f2b 100644
---- a/fs/smb/client/namespace.c
-+++ b/fs/smb/client/namespace.c
-@@ -168,6 +168,21 @@ static char *automount_fullpath(struct dentry *dentry, void *page)
- return s;
- }
-
-+static void fs_context_set_ids(struct smb3_fs_context *ctx)
-+{
-+ kuid_t uid = current_fsuid();
-+ kgid_t gid = current_fsgid();
-+
-+ if (ctx->multiuser) {
-+ if (!ctx->uid_specified)
-+ ctx->linux_uid = uid;
-+ if (!ctx->gid_specified)
-+ ctx->linux_gid = gid;
-+ }
-+ if (!ctx->cruid_specified)
-+ ctx->cred_uid = uid;
-+}
-+
- /*
- * Create a vfsmount that we can automount
- */
-@@ -205,6 +220,7 @@ static struct vfsmount *cifs_do_automount(struct path *path)
- tmp.leaf_fullpath = NULL;
- tmp.UNC = tmp.prepath = NULL;
- tmp.dfs_root_ses = NULL;
-+ fs_context_set_ids(&tmp);
-
- rc = smb3_fs_context_dup(ctx, &tmp);
- if (rc) {
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 9cc5bf32f6f2..7462fb1fc99e 100644
--- a/include/linux/efi.h
@@ -1493,7 +1306,7 @@ index 9cc5bf32f6f2..7462fb1fc99e 100644
enum efi_secureboot_mode efi_get_secureboot_mode(efi_get_variable_t *get_var)
{
diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h
-index 472cb16458b0..7c0f6dd800cb 100644
+index ed3d517460f8..93ff72b07031 100644
--- a/include/linux/lsm_hook_defs.h
+++ b/include/linux/lsm_hook_defs.h
@@ -407,6 +407,8 @@ LSM_HOOK(void, LSM_RET_VOID, bpf_prog_free_security, struct bpf_prog_aux *aux)
@@ -1773,183 +1586,8 @@ index a2ff4242e623..f0d2be1ee4f1 100644
}
int module_sig_check(struct load_info *info, int flags)
-diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c
-index 88965e2068ac..ebc5728aab4e 100644
---- a/net/openvswitch/flow_netlink.c
-+++ b/net/openvswitch/flow_netlink.c
-@@ -48,6 +48,7 @@ struct ovs_len_tbl {
-
- #define OVS_ATTR_NESTED -1
- #define OVS_ATTR_VARIABLE -2
-+#define OVS_COPY_ACTIONS_MAX_DEPTH 16
-
- static bool actions_may_change_flow(const struct nlattr *actions)
- {
-@@ -2545,13 +2546,15 @@ static int __ovs_nla_copy_actions(struct net *net, const struct nlattr *attr,
- const struct sw_flow_key *key,
- struct sw_flow_actions **sfa,
- __be16 eth_type, __be16 vlan_tci,
-- u32 mpls_label_count, bool log);
-+ u32 mpls_label_count, bool log,
-+ u32 depth);
-
- static int validate_and_copy_sample(struct net *net, const struct nlattr *attr,
- const struct sw_flow_key *key,
- struct sw_flow_actions **sfa,
- __be16 eth_type, __be16 vlan_tci,
-- u32 mpls_label_count, bool log, bool last)
-+ u32 mpls_label_count, bool log, bool last,
-+ u32 depth)
- {
- const struct nlattr *attrs[OVS_SAMPLE_ATTR_MAX + 1];
- const struct nlattr *probability, *actions;
-@@ -2602,7 +2605,8 @@ static int validate_and_copy_sample(struct net *net, const struct nlattr *attr,
- return err;
-
- err = __ovs_nla_copy_actions(net, actions, key, sfa,
-- eth_type, vlan_tci, mpls_label_count, log);
-+ eth_type, vlan_tci, mpls_label_count, log,
-+ depth + 1);
-
- if (err)
- return err;
-@@ -2617,7 +2621,8 @@ static int validate_and_copy_dec_ttl(struct net *net,
- const struct sw_flow_key *key,
- struct sw_flow_actions **sfa,
- __be16 eth_type, __be16 vlan_tci,
-- u32 mpls_label_count, bool log)
-+ u32 mpls_label_count, bool log,
-+ u32 depth)
- {
- const struct nlattr *attrs[OVS_DEC_TTL_ATTR_MAX + 1];
- int start, action_start, err, rem;
-@@ -2660,7 +2665,8 @@ static int validate_and_copy_dec_ttl(struct net *net,
- return action_start;
-
- err = __ovs_nla_copy_actions(net, actions, key, sfa, eth_type,
-- vlan_tci, mpls_label_count, log);
-+ vlan_tci, mpls_label_count, log,
-+ depth + 1);
- if (err)
- return err;
-
-@@ -2674,7 +2680,8 @@ static int validate_and_copy_clone(struct net *net,
- const struct sw_flow_key *key,
- struct sw_flow_actions **sfa,
- __be16 eth_type, __be16 vlan_tci,
-- u32 mpls_label_count, bool log, bool last)
-+ u32 mpls_label_count, bool log, bool last,
-+ u32 depth)
- {
- int start, err;
- u32 exec;
-@@ -2694,7 +2701,8 @@ static int validate_and_copy_clone(struct net *net,
- return err;
-
- err = __ovs_nla_copy_actions(net, attr, key, sfa,
-- eth_type, vlan_tci, mpls_label_count, log);
-+ eth_type, vlan_tci, mpls_label_count, log,
-+ depth + 1);
- if (err)
- return err;
-
-@@ -3063,7 +3071,7 @@ static int validate_and_copy_check_pkt_len(struct net *net,
- struct sw_flow_actions **sfa,
- __be16 eth_type, __be16 vlan_tci,
- u32 mpls_label_count,
-- bool log, bool last)
-+ bool log, bool last, u32 depth)
- {
- const struct nlattr *acts_if_greater, *acts_if_lesser_eq;
- struct nlattr *a[OVS_CHECK_PKT_LEN_ATTR_MAX + 1];
-@@ -3111,7 +3119,8 @@ static int validate_and_copy_check_pkt_len(struct net *net,
- return nested_acts_start;
-
- err = __ovs_nla_copy_actions(net, acts_if_lesser_eq, key, sfa,
-- eth_type, vlan_tci, mpls_label_count, log);
-+ eth_type, vlan_tci, mpls_label_count, log,
-+ depth + 1);
-
- if (err)
- return err;
-@@ -3124,7 +3133,8 @@ static int validate_and_copy_check_pkt_len(struct net *net,
- return nested_acts_start;
-
- err = __ovs_nla_copy_actions(net, acts_if_greater, key, sfa,
-- eth_type, vlan_tci, mpls_label_count, log);
-+ eth_type, vlan_tci, mpls_label_count, log,
-+ depth + 1);
-
- if (err)
- return err;
-@@ -3152,12 +3162,16 @@ static int __ovs_nla_copy_actions(struct net *net, const struct nlattr *attr,
- const struct sw_flow_key *key,
- struct sw_flow_actions **sfa,
- __be16 eth_type, __be16 vlan_tci,
-- u32 mpls_label_count, bool log)
-+ u32 mpls_label_count, bool log,
-+ u32 depth)
- {
- u8 mac_proto = ovs_key_mac_proto(key);
- const struct nlattr *a;
- int rem, err;
-
-+ if (depth > OVS_COPY_ACTIONS_MAX_DEPTH)
-+ return -EOVERFLOW;
-+
- nla_for_each_nested(a, attr, rem) {
- /* Expected argument lengths, (u32)-1 for variable length. */
- static const u32 action_lens[OVS_ACTION_ATTR_MAX + 1] = {
-@@ -3355,7 +3369,7 @@ static int __ovs_nla_copy_actions(struct net *net, const struct nlattr *attr,
- err = validate_and_copy_sample(net, a, key, sfa,
- eth_type, vlan_tci,
- mpls_label_count,
-- log, last);
-+ log, last, depth);
- if (err)
- return err;
- skip_copy = true;
-@@ -3426,7 +3440,7 @@ static int __ovs_nla_copy_actions(struct net *net, const struct nlattr *attr,
- err = validate_and_copy_clone(net, a, key, sfa,
- eth_type, vlan_tci,
- mpls_label_count,
-- log, last);
-+ log, last, depth);
- if (err)
- return err;
- skip_copy = true;
-@@ -3440,7 +3454,8 @@ static int __ovs_nla_copy_actions(struct net *net, const struct nlattr *attr,
- eth_type,
- vlan_tci,
- mpls_label_count,
-- log, last);
-+ log, last,
-+ depth);
- if (err)
- return err;
- skip_copy = true;
-@@ -3450,7 +3465,8 @@ static int __ovs_nla_copy_actions(struct net *net, const struct nlattr *attr,
- case OVS_ACTION_ATTR_DEC_TTL:
- err = validate_and_copy_dec_ttl(net, a, key, sfa,
- eth_type, vlan_tci,
-- mpls_label_count, log);
-+ mpls_label_count, log,
-+ depth);
- if (err)
- return err;
- skip_copy = true;
-@@ -3495,7 +3511,8 @@ int ovs_nla_copy_actions(struct net *net, const struct nlattr *attr,
-
- (*sfa)->orig_len = nla_len(attr);
- err = __ovs_nla_copy_actions(net, attr, key, sfa, key->eth.type,
-- key->eth.vlan.tci, mpls_label_count, log);
-+ key->eth.vlan.tci, mpls_label_count, log,
-+ 0);
- if (err)
- ovs_nla_free_flow_actions(*sfa);
-
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
-index cb6406f485a9..71e1f15d9dce 100644
+index f7c4d3fe4381..7fd1ef7930c6 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -22,6 +22,7 @@
@@ -1960,7 +1598,7 @@ index cb6406f485a9..71e1f15d9dce 100644
static bool module_enabled;
/* Are we using CONFIG_MODVERSIONS? */
-@@ -1987,6 +1988,12 @@ static void write_buf(struct buffer *b, const char *fname)
+@@ -1988,6 +1989,12 @@ static void write_buf(struct buffer *b, const char *fname)
}
}
@@ -1973,7 +1611,7 @@ index cb6406f485a9..71e1f15d9dce 100644
static void write_if_changed(struct buffer *b, const char *fname)
{
char *tmp;
-@@ -2047,6 +2054,7 @@ static void write_mod_c_file(struct module *mod)
+@@ -2048,6 +2055,7 @@ static void write_mod_c_file(struct module *mod)
add_depends(&buf, mod);
add_moddevtable(&buf, mod);
add_srcversion(&buf, mod);
@@ -2055,10 +1693,10 @@ index 68d19632aeb7..ef348935b6ff 100644
static int __init lockdown_lsm_init(void)
diff --git a/security/security.c b/security/security.c
-index 266cec94369b..c572a4da96b2 100644
+index 2cfecdb054c3..4e5fc4ec5896 100644
--- a/security/security.c
+++ b/security/security.c
-@@ -5248,6 +5248,18 @@ int security_locked_down(enum lockdown_reason what)
+@@ -5283,6 +5283,18 @@ int security_locked_down(enum lockdown_reason what)
}
EXPORT_SYMBOL(security_locked_down);