06 Sep, 2005

8 commits

  • We could inline i2c_adapter_id, as it is really, really short. Doing
    so saves a few bytes both in i2c-core and in the drivers using this
    function.

    before after diff
    drivers/hwmon/adm1026.ko 41344 41305 -39
    drivers/hwmon/asb100.ko 27325 27246 -79
    drivers/hwmon/gl518sm.ko 20824 20785 -39
    drivers/hwmon/it87.ko 26419 26380 -39
    drivers/hwmon/lm78.ko 21424 21385 -39
    drivers/hwmon/lm85.ko 41034 40939 -95
    drivers/hwmon/w83781d.ko 39561 39514 -47
    drivers/hwmon/w83792d.ko 32979 32932 -47
    drivers/i2c/i2c-core.ko 24708 24531 -177

    Signed-off-by: Jean Delvare
    Signed-off-by: Greg Kroah-Hartman

    Jean Delvare
     
  • I would like to announce support for W83792D chip. This driver was developed
    by Winbond Electronics Corp. I added sysfs attributes callbacks infrastructure
    plus various code fixes and codingstyle cleanups. I would like to thank Winbond
    for supporting free software.

    This patch is against 2.6.13rc3 plus hwmon-class and hwmon-split.
    Separate patch for documantation and hwmon class register will follow.

    Signed-off-by: Rudolf Marek
    Signed-off-by: Chunhao Huang
    Signed-off-by: Greg Kroah-Hartman

    R.Marek@sh.cvut.cz
     
  • Move the definitions of i2c_is_isa_client and i2c_is_isa_adapter from
    i2c.h to i2c-isa.h. Only hybrid drivers still need them.

    Signed-off-by: Greg Kroah-Hartman

    Jean Delvare
     
  • Kill normal_isa in header files, documentation and all chip drivers, as
    it is no more used.

    normal_i2c could be renamed to normal, but I decided not to do so at the
    moment, so as to limit the number of changes. This might be done later
    as part of the i2c_probe/i2c_detect merge.

    Signed-off-by: Greg Kroah-Hartman

    Jean Delvare
     
  • Convert i2c-isa from a dumb i2c_adapter into a pseudo i2c-core for ISA
    hardware monitoring drivers. The isa i2c_adapter is no more registered
    with i2c-core, drivers have to explicitely connect to it using the new
    i2c_isa_{add,del}_driver interface.

    At this point, all ISA chip drivers are useless, because they still
    register with i2c-core in the hope i2c-isa is registered there as well,
    but it isn't anymore.

    The fake bus will be named i2c-9191 in sysfs. This is the number it
    already had internally in various places, so it's not exactly new,
    except that now the number is seen in userspace as well. This shouldn't
    be a problem until someone really has 9192 I2C busses in a given system
    ;)

    The fake bus will no more show in "i2cdetect -l", as it won't be seen by
    i2c-dev anymore (not being registered with i2c-core), which is a good
    thing, as i2cdetect/i2cdump/i2cset cannot operate on this fake bus
    anyway.

    Signed-off-by: Greg Kroah-Hartman

    Jean Delvare
     
  • Temporarily export a few structures and functions from i2c-core, because we
    will soon need them in i2c-isa.

    Signed-off-by: Jean Delvare
    Signed-off-by: Greg Kroah-Hartman

    Jean Delvare
     
  • This patch adds the sysfs class "hwmon" for use by hardware monitoring
    (sensors) chip drivers. It also fixes up the related Kconfig/Makefile
    bits.

    Signed-off-by: Mark M. Hoffman
    Signed-off-by: Jean Delvare
    Signed-off-by: Greg Kroah-Hartman

    Mark M. Hoffman
     
  • Move the inline function kobj_to_i2c_client() from max6875.c to i2c.h.

    Signed-off-by: Ben Gardner
    Signed-off-by: Greg Kroah-Hartman

    bgardner@wabtec.com
     

05 Sep, 2005

32 commits

  • Linus Torvalds
     
  • Linus Torvalds
     
  • Linus Torvalds
     
  • Linus Torvalds
     
  • On s390 the lock value used for spinlocks consists of the lower 32 bits of the
    PSW that holds the lock. If this address happens to be on a four gigabyte
    boundary the lock is left unlocked. This allows other cpus to grab the same
    lock and enter a lock protected code path concurrently. In theory this can
    happen if the vmalloc area for the code of a module crosses a 4 GB boundary.

    Signed-off-by: Heiko Carstens
    Signed-off-by: Martin Schwidefsky
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Heiko Carstens
     
  • debug feature changes/bug fixes:

    - Use get_clock() function instead of private inline assembly.

    - Use 'struct timeval' instead of 'struct timespec' for call to
    tod_to_timeval(). Now the microsecond part of the timestamp is correct
    again.

    - Fix a locking problem: when creating a snapshot of the current content
    of the debug areas, lock the entire debug_info object.

    Signed-off-by: Michael Holzheu
    Signed-off-by: Martin Schwidefsky
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Michael Holzheu
     
  • The new machine check handler still has a few bugs.

    1) The system entry time has to be stored in the machine check handler,

    2) the machine check return psw may not be stored at the usual place
    because it might overwrite the return psw of the interrupted context,

    3) the return address for the call to s390_handle_mcck in the i/o interrupt
    handler is not correct,

    4) the system call cleanup has to take the different save area of the
    machine check handler into account,

    5) the machine check handler may not call UPDATE_VTIME before
    CREATE_STACK_FRAME, and

    6) the io leave path needs a critical section cleanup to make sure that the
    TIF_MCCK_PENDING bit is really checked before switching back to user space.

    Signed-off-by: Martin Schwidefsky
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Martin Schwidefsky
     
  • This file seems to be an accident.

    Signed-off-by: Adrian Bunk
    Signed-off-by: Chris Zankel
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Adrian Bunk
     
  • "extern inline" doesn't make sense.

    Signed-off-by: Adrian Bunk
    Signed-off-by: Chris Zankel
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Adrian Bunk
     
  • We were leaking pmd pages when 3_LEVEL_PGTABLES was enabled. This fixes that.

    Signed-off-by: Jeff Dike
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Jeff Dike
     
  • There is a lot of code which is duplicated between the 2 and 3 level
    implementation, with the only difference that the 3-level implementation is a
    bit more generalized (instead of accessing directly pte_t.pte, it uses the
    appropriate access macros).

    So this code is joined together.

    As obvious, a "core code nice cleanup" is not a "stability-friendly patch" so
    usual care applies.

    Signed-off-by: Paolo 'Blaisorblade' Giarrusso
    Signed-off-by: Jeff Dike
    Cc: Paolo Giarrusso
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Jeff Dike
     
  • Normally, activate_mm() is called from exec(), and thus it used to be a
    no-op because we use a completely new "MM context" on the host (for
    instance, a new process), and so we didn't need to flush any "TLB entries"
    (which for us are the set of memory mappings for the host process from the
    virtual "RAM" file).

    Kernel threads, instead, are usually handled in a different way. So, when
    for AIO we call use_mm(), things used to break and so Benjamin implemented
    activate_mm(). However, that is only needed for AIO, and could slow down
    exec() inside UML, so be smart: detect being called for AIO (via
    PF_BORROWED_MM) and do the full flush only in that situation.

    Comment also the caller so that people won't go breaking UML without
    noticing. I also rely on the caller's locks for testing current->flags.

    Signed-off-by: Paolo 'Blaisorblade' Giarrusso
    CC: Benjamin LaHaise
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Paolo 'Blaisorblade' Giarrusso
     
  • This patch implements the new ptrace option PTRACE_SYSEMU_SINGLESTEP, which
    can be used by UML to singlestep a process: it will receive SINGLESTEP
    interceptions for normal instructions and syscalls, but syscall execution will
    be skipped just like with PTRACE_SYSEMU.

    Signed-off-by: Bodo Stroesser
    Signed-off-by: Paolo 'Blaisorblade' Giarrusso
    Cc: Jeff Dike
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Bodo Stroesser
     
  • Jeff Dike ,
    Paolo 'Blaisorblade' Giarrusso ,
    Bodo Stroesser

    Adds a new ptrace(2) mode, called PTRACE_SYSEMU, resembling PTRACE_SYSCALL
    except that the kernel does not execute the requested syscall; this is useful
    to improve performance for virtual environments, like UML, which want to run
    the syscall on their own.

    In fact, using PTRACE_SYSCALL means stopping child execution twice, on entry
    and on exit, and each time you also have two context switches; with SYSEMU you
    avoid the 2nd stop and so save two context switches per syscall.

    Also, some architectures don't have support in the host for changing the
    syscall number via ptrace(), which is currently needed to skip syscall
    execution (UML turns any syscall into getpid() to avoid it being executed on
    the host). Fixing that is hard, while SYSEMU is easier to implement.

    * This version of the patch includes some suggestions of Jeff Dike to avoid
    adding any instructions to the syscall fast path, plus some other little
    changes, by myself, to make it work even when the syscall is executed with
    SYSENTER (but I'm unsure about them). It has been widely tested for quite a
    lot of time.

    * Various fixed were included to handle the various switches between
    various states, i.e. when for instance a syscall entry is traced with one of
    PT_SYSCALL / _SYSEMU / _SINGLESTEP and another one is used on exit.
    Basically, this is done by remembering which one of them was used even after
    the call to ptrace_notify().

    * We're combining TIF_SYSCALL_EMU with TIF_SYSCALL_TRACE or TIF_SINGLESTEP
    to make do_syscall_trace() notice that the current syscall was started with
    SYSEMU on entry, so that no notification ought to be done in the exit path;
    this is a bit of a hack, so this problem is solved in another way in next
    patches.

    * Also, the effects of the patch:
    "Ptrace - i386: fix Syscall Audit interaction with singlestep"
    are cancelled; they are restored back in the last patch of this series.

    Detailed descriptions of the patches doing this kind of processing follow (but
    I've already summed everything up).

    * Fix behaviour when changing interception kind #1.

    In do_syscall_trace(), we check the status of the TIF_SYSCALL_EMU flag
    only after doing the debugger notification; but the debugger might have
    changed the status of this flag because he continued execution with
    PTRACE_SYSCALL, so this is wrong. This patch fixes it by saving the flag
    status before calling ptrace_notify().

    * Fix behaviour when changing interception kind #2:
    avoid intercepting syscall on return when using SYSCALL again.

    A guest process switching from using PTRACE_SYSEMU to PTRACE_SYSCALL
    crashes.

    The problem is in arch/i386/kernel/entry.S. The current SYSEMU patch
    inhibits the syscall-handler to be called, but does not prevent
    do_syscall_trace() to be called after this for syscall completion
    interception.

    The appended patch fixes this. It reuses the flag TIF_SYSCALL_EMU to
    remember "we come from PTRACE_SYSEMU and now are in PTRACE_SYSCALL", since
    the flag is unused in the depicted situation.

    * Fix behaviour when changing interception kind #3:
    avoid intercepting syscall on return when using SINGLESTEP.

    When testing 2.6.9 and the skas3.v6 patch, with my latest patch and had
    problems with singlestepping on UML in SKAS with SYSEMU. It looped
    receiving SIGTRAPs without moving forward. EIP of the traced process was
    the same for all SIGTRAPs.

    What's missing is to handle switching from PTRACE_SYSCALL_EMU to
    PTRACE_SINGLESTEP in a way very similar to what is done for the change from
    PTRACE_SYSCALL_EMU to PTRACE_SYSCALL_TRACE.

    I.e., after calling ptrace(PTRACE_SYSEMU), on the return path, the debugger is
    notified and then wake ups the process; the syscall is executed (or skipped,
    when do_syscall_trace() returns 0, i.e. when using PTRACE_SYSEMU), and
    do_syscall_trace() is called again. Since we are on the return path of a
    SYSEMU'd syscall, if the wake up is performed through ptrace(PTRACE_SYSCALL),
    we must still avoid notifying the parent of the syscall exit. Now, this
    behaviour is extended even to resuming with PTRACE_SINGLESTEP.

    Signed-off-by: Paolo 'Blaisorblade' Giarrusso
    Cc: Jeff Dike
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Laurent Vivier
     
  • Use the builtin functions for memset/memclr/memcpy, special optimizations for
    page operations have dedicated functions now. Uninline memmove/memchr and
    move all functions into a single file and clean it up a little.

    Signed-off-by: Roman Zippel
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Roman Zippel
     
  • Move a few cache functions into its own file and fix flush_icache_range() so
    it can handle both kernel and user addresses correctly (assuming context is
    set correctly).

    Turn copy_to_user_page/copy_from_user_page into inline functions and add a
    missing cache flush.

    Signed-off-by: Roman Zippel
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Roman Zippel
     
  • The timers lack .suspend/.resume methods. Because of this, jiffies got a
    big compensation after a S3 resume. And then softlockup watchdog reports
    an oops. This occured with HPET enabled, but it's also possible for other
    timers.

    Signed-off-by: Shaohua Li
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Shaohua Li
     
  • This adds type-checking to pm_message_t, so that people can't confuse it
    with int or u32. It also allows us to fix "disk yoyo" during suspend (disk
    spinning down/up/down).

    [We've tried that before; since that cpufreq problems were fixed and I've
    tried make allyes config and fixed resulting damage.]

    Signed-off-by: Pavel Machek
    Signed-off-by: Alexander Nyberg
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Pavel Machek
     
  • for_each_cpu walks through all processors in cpu_possible_map, which is
    defined as cpu_callout_map on i386 and isn't initialised until all
    processors have been booted. This breaks things which do for_each_cpu
    iterations early during boot. So, define cpu_possible_map as a bitmap with
    NR_CPUS bits populated. This was triggered by a patch i'm working on which
    does alloc_percpu before bringing up secondary processors.

    From: Alexander Nyberg

    i386-boottime-for_each_cpu-broken.patch
    i386-boottime-for_each_cpu-broken-fix.patch

    The SMP version of __alloc_percpu checks the cpu_possible_map before
    allocating memory for a certain cpu. With the above patches the BSP cpuid
    is never set in cpu_possible_map which breaks CONFIG_SMP on uniprocessor
    machines (as soon as someone tries to dereference something allocated via
    __alloc_percpu, which in fact is never allocated since the cpu is not set
    in cpu_possible_map).

    Signed-off-by: Zwane Mwaikambo
    Signed-off-by: Alexander Nyberg
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Zwane Mwaikambo
     
  • Add a clone operation for pgd updates.

    This helps complete the encapsulation of updates to page tables (or pages
    about to become page tables) into accessor functions rather than using
    memcpy() to duplicate them. This is both generally good for consistency
    and also necessary for running in a hypervisor which requires explicit
    updates to page table entries.

    The new function is:

    clone_pgd_range(pgd_t *dst, pgd_t *src, int count);

    dst - pointer to pgd range anwhere on a pgd page
    src - ""
    count - the number of pgds to copy.

    dst and src can be on the same page, but the range must not overlap
    and must not cross a page boundary.

    Note that I ommitted using this call to copy pgd entries into the
    software suspend page root, since this is not technically a live paging
    structure, rather it is used on resume from suspend. CC'ing Pavel in case
    he has any feedback on this.

    Thanks to Chris Wright for noticing that this could be more optimal in
    PAE compiles by eliminating the memset.

    Signed-off-by: Zachary Amsden
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Zachary Amsden
     
  • This patch adds a notify to the die_nmi notify that the system is about to
    be taken down. If the notify is handled with a NOTIFY_STOP return, the
    system is given a new lease on life.

    We also change the nmi watchdog to carry on if die_nmi returns.

    This give debug code a chance to a) catch watchdog timeouts and b) possibly
    allow the system to continue, realizing that the time out may be due to
    debugger activities such as single stepping which is usually done with
    "other" cpus held.

    Signed-off-by: George Anzinger
    Cc: Keith Owens
    Signed-off-by: George Anzinger
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    George Anzinger
     
  • Introduce a write acessor for updating the current LDT. This is required
    for hypervisors like Xen that do not allow LDT pages to be directly
    written.

    Testing - here's a fun little LDT test that can be trivially modified to
    test limits as well.

    /*
    * Copyright (c) 2005, Zachary Amsden (zach@vmware.com)
    * This is licensed under the GPL.
    */

    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #define __KERNEL__
    #include

    void main(void)
    {
    struct user_desc desc;
    char *code;
    unsigned long long tsc;

    code = (char *)mmap(0, 8192, PROT_EXEC|PROT_READ|PROT_WRITE,
    MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
    desc.entry_number = 0;
    desc.base_addr = code;
    desc.limit = 1;
    desc.seg_32bit = 1;
    desc.contents = MODIFY_LDT_CONTENTS_CODE;
    desc.read_exec_only = 0;
    desc.limit_in_pages = 1;
    desc.seg_not_present = 0;
    desc.useable = 1;
    if (modify_ldt(1, &desc, sizeof(desc)) != 0) {
    perror("modify_ldt");
    }
    printf("code base is 0x%08x\n", (unsigned)code);
    code[0x0ffe] = 0x0f; /* rdtsc */
    code[0x0fff] = 0x31;
    code[0x1000] = 0xcb; /* lret */
    __asm__ __volatile("lcall $7,$0xffe" : "=A" (tsc));
    printf("TSC is 0x%016llx\n", tsc);
    }

    Signed-off-by: Zachary Amsden
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Zachary Amsden
     
  • The pushf/popf in switch_to are ONLY used to switch IOPL. Making this
    explicit in C code is more clear. This pushf/popf pair was added as a
    bugfix for leaking IOPL to unprivileged processes when using
    sysenter/sysexit based system calls (sysexit does not restore flags).

    When requesting an IOPL change in sys_iopl(), it is just as easy to change
    the current flags and the flags in the stack image (in case an IRET is
    required), but there is no reason to force an IRET if we came in from the
    SYSENTER path.

    This change is the minimal solution for supporting a paravirtualized Linux
    kernel that allows user processes to run with I/O privilege. Other
    solutions require radical rewrites of part of the low level fault / system
    call handling code, or do not fully support sysenter based system calls.

    Unfortunately, this added one field to the thread_struct. But as a bonus,
    on P4, the fastest time measured for switch_to() went from 312 to 260
    cycles, a win of about 17% in the fast case through this performance
    critical path.

    Signed-off-by: Zachary Amsden
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Zachary Amsden
     
  • Privilege checking cleanup. Originally, these diffs were much greater, but
    recent cleanups in Linux have already done much of the cleanup. I added
    some explanatory comments in places where the reasoning behind certain
    tests is rather subtle.

    Also, in traps.c, we can skip the user_mode check in handle_BUG(). The
    reason is, there are only two call chains - one via die_if_kernel() and one
    via do_page_fault(), both entering from die(). Both of these paths already
    ensure that a kernel mode failure has happened. Also, the original check
    here, if (user_mode(regs)) was insufficient anyways, since it would not
    rule out BUG faults from V8086 mode execution.

    Saving the %ss segment in show_regs() rather than assuming a fixed value
    also gives better information about the current kernel state in the
    register dump.

    Signed-off-by: Zachary Amsden
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Zachary Amsden
     
  • Some more assembler cleanups I noticed along the way.

    Signed-off-by: Zachary Amsden
    Cc: "H. Peter Anvin"
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Zachary Amsden
     
  • Noticed by Chuck Ebbert: the .ldt entry of the TSS was set up incorrectly.
    It never mattered since this was a leftover from old times, so remove it.

    Signed-off-by: Ingo Molnar
    Signed-off-by: Adrian Bunk
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Ingo Molnar
     
  • Also, setting PDPEs in PAE mode does not require atomic operations, since the
    PDPEs are cached by the processor, and only reloaded on an explicit or
    implicit reload of CR3.

    Since the four PDPEs must always be present in an active root, and the kernel
    PDPE is never updated, we are safe even from SMIs and interrupts / NMIs using
    task gates (which reload CR3). Actually, much of this is moot, since the user
    PDPEs are never updated either, and the only usage of task gates is by the
    doublefault handler. It appears the only place PGDs get updated in PAE mode
    is in init_low_mappings() / zap_low_mapping() for initial page table creation
    and recovery from ACPI sleep state, and these sites are safe by inspection.
    Getting rid of the cmpxchg8b saves code space and 720 cycles in pgd_alloc on
    P4.

    Signed-off-by: Zachary Amsden
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Zachary Amsden
     
  • GCC can generate better code around descriptor update and access functions
    when there is not an explicit "eax" register constraint.

    Testing: You won't boot if this is messed up, since the TSS descriptor will be
    corrupted. Verified the assembler and booted.

    Signed-off-by: Zachary Amsden
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Zachary Amsden
     
  • i386 inline assembler cleanup.

    This change encapsulates descriptor and task register management. Also,
    it is possible to improve assembler generation in two cases; savesegment
    may store the value in a register instead of a memory location, which
    allows GCC to optimize stack variables into registers, and MOV MEM, SEG
    is always a 16-bit write to memory, making the casting in math-emu
    unnecessary.

    Signed-off-by: Zachary Amsden
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Zachary Amsden
     
  • i386 arch cleanup. Introduce the serialize macro to serialize processor
    state. Why the microcode update needs it I am not quite sure, since wrmsr()
    is already a serializing instruction, but it is a microcode update, so I will
    keep the semantic the same, since this could be a timing workaround. As far
    as I can tell, this has always been there since the original microcode update
    source.

    Signed-off-by: Zachary Amsden
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Zachary Amsden
     
  • i386 Inline asm cleanup. Use cr/dr accessor functions.

    Also, a potential bugfix. Also, some CR accessors really should be volatile.
    Reads from CR0 (numeric state may change in an exception handler), writes to
    CR4 (flipping CR4.TSD) and reads from CR2 (page fault) prevent instruction
    re-ordering. I did not add memory clobber to CR3 / CR4 / CR0 updates, as it
    was not there to begin with, and in no case should kernel memory be clobbered,
    except when doing a TLB flush, which already has memory clobber.

    I noticed that page invalidation does not have a memory clobber. I can't find
    a bug as a result, but there is definitely a potential for a bug here:

    #define __flush_tlb_single(addr) \
    __asm__ __volatile__("invlpg %0": :"m" (*(char *) addr))

    Signed-off-by: Zachary Amsden
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Zachary Amsden
     
  • This is subarch update for ES7000. I've modified platform check code and
    removed unnecessary OEM table parsing for newer systems that don't use OEM
    information during boot. Parsing the table in fact is causing problems,
    and the platform doesn't get recognized. The patch only affects the ES7000
    subach.

    Signed-off-by:
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Natalie.Protasevich@unisys.com